#include "event_app.h"
#include "event_board.h"
#include "rfid_app.h"
#include "device_parameter.h"

/**
 * @brief 判断该任务是否会被执行
 *
 * @param TaskLevel - 任务级别
 * @return bool     - 可执行状态（true：可执行 false：不可执行）
 * @note 该函数用于判断任务是否会被执行，若任务列表内存在任务则比对级别，优先级高则会被执行
 */
static bool EventJudgeWhetherTheNewActionIsValid(SystemAction_t NewAction);

/**
 * @brief 启动获取服务器报文
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventStartGetServerMessage(void);

/**
 * @brief 验证功能密钥
 *
 * @param pKeyValueIn - 密钥
 * @param KeyLength   - 密钥长度
 * @return bool       - 验证结果（true：成功 false：失败）
 */
static bool EventVerifyIfFunctionPassword(const void *pKeyValueIn, uint8_t KeyLength);

/**
 * @brief 用户鉴权处理方法
 *
 * @param KeyType     - 密钥类型
 * @param pKeyValueIn - 密钥
 * @param NumberOfKey - 密钥长度
 * @param DoorAction  - 门动作
 */
static void EventUserAuthenticationHandler(uint8_t KeyType, const void *pKeyValueIn, uint8_t NumberOfKey, uint8_t DoorAction);

/**
 * @brief 任务执行超时回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventTaskScheduleTimeoutCallback(void);

/**
 * @brief 网络保持连接超时回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventNetworkKeepLiveTimeoutCallback(void);

/**
 * @brief 心跳超时回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventGetServerMessageTimeoutCallback(void);

/**
 * @brief 鉴权错误时间重置回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventAuthenticationErrorResetTimeoutCallback(void);

/**
 * @brief 退出恢复出厂设置任务回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventExitFactorySettingTaskCallback(void);

/**
 * @brief 启动恢复出厂设置任务回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventStartFactorySettingTaskCallback(void);

/**
 * @brief 退出引导程序更新任务回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventExitBootloaderUpdateTaskCallback(void);

/**
 * @brief 启动引导程序更新任务回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventStartBootloaderUpdateTaskCallback(void);

/**
 * @brief 退出应用程序更新任务回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventExitApplicationUpdateTaskCallback(void);

/**
 * @brief 启动应用程序更新任务回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventStartApplicationUpdateTaskCallback(void);

/**
 * @brief 退出设备复位任务回调
 *
 */
static bool EventExitRebootTaskCallback(void);

/**
 * @brief 启动设备复位任务回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventStartRebootTaskCallback(void);

/**
 * @brief 退出自检任务回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventExitSelftestTaskCallback(void);

/**
 * @brief 启动自检任务回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventStartSelftestTaskCallback(void);

/**
 * @brief 退出键入管理员密码回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventExitKeyInAdminPasswordCallback(void);

/**
 * @brief 启动键入管理员密码回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventStartKeyInAdminPasswordTaskCallback(void);

/**
 * @brief 退出验证常开权限任务回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventExitVerifyNormalOpenPermissionCallback(void);

/**
 * @brief 启动验证常开权限任务回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventStartVerifyNormalOpenPermissionCallback(void);

/**
 * @brief 退出本地注册任务回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventExitLocalRegisterTaskCallback(void);

/**
 * @brief 启动本地注册任务回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventStartLocalRegisterTaskCallback(void);

/**
 * @brief 退出在线注册回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventExitOnlineRegisterTaskCallback(void);

/**
 * @brief 启动在线注册回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventStartOnlineRegisterTaskCallback(void);

/**
 * @brief 退出请求服务器信息回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventExitRequestServerInformationTaskCallback(void);

/**
 * @brief 启动请求服务器信息回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventStartRequestServerInformationTaskCallback(void);

/**
 * @brief 退出主动请求服务器信息回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventExitActivelyRequestServerMessageTaskCallback(void);

/**
 * @brief 启动主动请求服务器信息回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventStartActivelyRequestServerMessageTaskCallback(void);

/**
 * @brief 退出信息上报回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventExitInformationReportingTaskCallback(void);

/**
 * @brief 启动信息上报回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventStartInformationReportingTaskCallback(void);

/**
 * @brief 退出警报上报任务回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventExitAlarmReportingTaskCallback(void);

/**
 * @brief 启动警报上报任务回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventStartAlarmReportingTaskCallback(void);

/**
 * @brief 退出推送在线注册用户状态任务回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventExitPushOnlineRegisterStatusTaskCallback(void);

/**
 * @brief 启动推送在线注册用户状态任务回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventStartPushOnlineRegisterStatusTaskCallback(void);

/**
 * @brief 退出开锁任务回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventExitDoorUnlockTaskCallback(void);

/**
 * @brief 启动开锁任务回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventStartDoorUnlockTaskCallback(void);

/**
 * @brief 退出提示设备处于锁定状态提示任务
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventExitDoorLockTaskCallback(void);

/**
 * @brief 启动提示设备处于锁定状态提示任务
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventStartDoorLockTaskCallback(void);

/**
 * @brief 退出读取卡片任务回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventExitReadCardTaskCallback(void);

/**
 * @brief 启动读取卡片任务回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventStartReadCardTaskCallback(void);

/**
 * @brief 退出外部模组验证任务回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventExitExternalModuleVerifyTaskCallback(void);

/**
 * @brief 启动外部模组验证任务回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventStartExternalModuleVerifyTaskCallback(void);

/**
 * @brief 退出键盘验证任务回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventExitKeyboardKeyscanfTaskCallback(void);

/**
 * @brief 启动键盘验证任务回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventStartKeyboardKeyscanfTaskCallback(void);

/**
 * @brief 退出反锁提示任务回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventExitLockedInTipTaskCallback(void);

/**
 * @brief 启动反锁提示任务回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventStartLockedInTipTaskCallback(void);

/**
 * @brief 退出假锁提示任务回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventExitFalseLockedTipTaskCallback(void);

/**
 * @brief 启动假锁提示任务回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventStartFalseLockedTipTaskCallback(void);

/**
 * @brief 退出撬锁提示任务回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventExitPickLockedTipTaskCallback(void);

/**
 * @brief 启动撬锁提示任务回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventStartPickLockedTipTaskCallback(void);

/**
 * @brief 退出钥匙提示任务回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventExitKeyInTipTaskCallback(void);

/**
 * @brief 启动钥匙提示任务回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventStartKeyInTipCallback(void);

/**
 * @brief 退出无线唤醒任务回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventExitWirelessWakeupTaskCallback(void);

/**
 * @brief 启动无线唤醒任务回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventStartWirelessWakeupTaskCallback(void);

/**
 * @brief 退出更新蓝牙广播任务回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventExitUpdateBluetoothRadioCallback(void);

/**
 * @brief 启动更新蓝牙广播任务回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventStartUpdateBluetoothRadioCallback(void);

/**
 * @brief 退出待机回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventExitStandbyTaskCallback(void);

/**
 * @brief 进入待机回调
 *
 * @return bool - 执行状态（true：成功 false：失败）
 */
static bool EventStartStandbyTaskCallback(void);

/**
 * @brief 初始化任务调度
 *
 * @return bool - 初始化状态（true：成功 false：失败）
 */
static void EventInitialisingTaskSchedule(void);

/**
 * @brief 删除当前任务
 *
 * @param Node - 任务节点
 */
static void EventDeleteCurrectTask(TaskScheduleNode_t Node);

/**
 * @brief 重置任务运行时间
 *
 * @param TaskLevel - 任务级别
 * @return bool     - 重置状态（true：成功 false：失败）
 */
static bool EventResetTaskRuntime(SystemAction_t TaskLevel);

/**
 * @brief 更新目标动作附带参数
 *
 * @param TaskLevel - 任务级别
 * @param pDataIn   - 附带数据
 * @param SizeIn    - 附带参数长度
 * @return bool     - 更新状态（true：成功 fasle：失败）
 */
static bool EventUpdateTargetActionAttachedParam(SystemAction_t TaskLevel, const void *pDataIn, uint8_t SizeIn);

/**
 * @brief 获取最高优先级任务
 *
 * @return TaskScheduleNode_t - 最高优先级任务节点
 */
static TaskScheduleNode_t EventGetMixPriorityTask(void);

/**
 * @brief 标志任务执行完成
 *
 * @param TaskLevel - 任务级别
 * @return bool     - 标志状态（true：成功 false：失败）
 */
static bool EventMarkTaskExecuteComplete(SystemAction_t TaskLevel);

/**
 * @brief 标志系统新动作
 *
 * @param TaskLevel    - 任务级别
 * @param pTaskExecute - 任务执行回调
 * @param pTaskExit    - 强制退出回调
 * @param Timeout      - 超时时间
 * @param AutoDestroy  - 任务自动销毁
 * @param pDataIn      - 附带数据
 * @param SizeIn       - 附带数据长度
 * @param EventCacheEn - 事件强制缓存使能
 * @return bool        - 标志状态（true：成功 false：失败）
 */
static bool EventMarkSystemNewAction(SystemAction_t TaskLevel, TaskExecuteCallback_t pTaskExecute, TaskExitCallback_t pTaskExit, uint16_t Timeout, uint8_t AutoDestroy, const void *pDataIn, uint8_t SizeIn, bool EventCacheEn);

/**
 * @brief 创建任务调度定时任务
 *
 */
static void EventCreateTaskScheduleTimer(void);

/**
 * @brief 创建网络保活定时器
 *
 */
static void EventCreateNetworkKeepLiveTimer(void);

/**
 * @brief 创建定时向服务器请求信息定时任务
 *
 */
static void EventCreateGetServerMessageTimer(void);

/**
 * @brief 创建鉴权错误重置时间定时任务
 *
 */
static void EventCreateAuthenticationErrorResetTimer(void);

/**
 * @brief 判断是否达到鉴权失败上限
 *
 * @param KeyType - 密钥类型
 * @return bool   - 判断状态（true：满足 false：不满足）
 */
static bool EventJudgeIfAuthFailureLimitReached(uint8_t KeyType);

/**
 * @brief 验证板载设备运行状态
 *
 * @return bool - 验证状态（true：正常 false：异常）
 */
static bool VerifyOnBoardDeviceOperatingStatus(void);

/**
 * @brief 获取自检的传感器类型
 *
 * @param CurrentOrder            - 当前自检的设备类型
 * @param pNextOrder              - 待自检的设备类型
 * @return DevGetSelfTestResult_t - 获取状态
 */
static DevGetSelfTestResult_t EventObtainTheTypeOfSensorForSelfTest(SelfTestOrder_t CurrentOrder, SelfTestOrder_t *pNextOrder);

/**
 * @brief 获取重置的传感器类型
 *
 * @param CurrentStep             - 当前重置的设备类型
 * @param pNextStep               - 待自检的设备类型
 * @return GetDeviceResetResult_t - 获取状态
 */
static GetDeviceResetResult_t EventObtainTheTypeOfSensorForReset(DeviceResetStep_t CurrentStep, DeviceResetStep_t *pNextStep);

/**
 * @brief 启动特定模组自检任务
 *
 * @param ModuleType             - 传感器类型
 * @return SelfTestStartResult_t - 启动状态
 */
static SelfTestStartResult_t EventInitiateModuleSpecificSelfTestTasks(SelfTestOrder_t ModuleType);

/**
 * @brief 启动特定模组重置任务
 *
 * @param ModuleType          - 传感器类型
 * @return ResetStartResult_t - 启动状态
 */
static ResetStartResult_t EventInitiateModuleSpecificResetTask(DeviceResetStep_t ModuleType);

/**
 * @brief 定时任务回调
 *
 */
static void EventTaskScheduledCallback(void);

/**
 * @brief 定时任务回调方法
 *
 */
static void EventScheduledTaskCallback(void);

/**
 * @brief 设备重启回调
 *
 */
static void EventDeviceRebootCallback(void);

/**
 * @brief 设备恢复出厂设置回调
 *
 */
static void EventRestoreFactoryCallback(void);

/**
 * @brief 设备自检任务回调
 *
 */
static void EventDeviceSelfTestCallback(void);

/**
 * @brief 固件更新回调
 *
 */
static void SystemFirmwarwUpdateCallback(void);

static TimedListNode_t TimedListNode = NULL;
static TimedTable_t TaskScheduleTimeNode = {0};
static TimedTable_t NetworkKeepLiveTimeNode = {0};
static TimedTable_t GetServerMessageTimeNode = {0};
static TimedTable_t AuthenticationErrResetTimeNode = {0};
static EventCenterStatusBit_t EventCenterStatusBit = {0};
static EventHandlerListNode_t EventHandlerListNode = NULL;
static TaskScheduleNode_t TaskScheduleNode = NULL, CurrectTaskScheduleNode = NULL;

/**
 * @brief 功能密码对照表
 *
 */
const char FunctionPasswordLookupTable[][10] = {
    {'1'},                                         // 获取网络质量
    {'2'},                                         // 打开常开模式
    {'3'},                                         // 获取电量
    {'9'},                                         // 启动网络附着
    {'9', '0', '3', '7', '0'},                     // 设备重置
    {'9', '0', '3', '7', '5', '7', '3', '6', '9'}, // 设备恢复出厂设置
};

static bool EventJudgeWhetherTheNewActionIsValid(SystemAction_t NewAction)
{
  TaskScheduleNode_t TmpListNode = TaskScheduleNode->NextItem;

  while (TmpListNode != TaskScheduleNode)
  {
    if (TmpListNode->AttachedParam.Level <= NewAction)
    {
      PRINT("[task]: new action is invalid, currect action: %d, new action: %d.\r\n", TmpListNode->AttachedParam.Level, NewAction);
      return false;
    }

    TmpListNode = TmpListNode->NextItem;
  }

  return true;
}

static bool EventStartGetServerMessage(void)
{
#if _NETWOK_FUNCTION_ENABLE_
  if (EventGetDeviceActivationStatus() == true)
  {
    if (EventGetVoltagePercentage() >= EVENT_LOW_VOLTAGE_THRESHOLD)
    {
      if (EventStartActivelyRequestServerTask() != true)
      {
        EventPlayEquipmentBusyStatus();
      }
    }
    else
    {
      EventPlayLowBattery();
    }
  }
  else
  {
    EventPlayDeviceNotAuthorized();
  }

  return true;

#else
  return false;
#endif
}

static bool EventVerifyIfFunctionPassword(const void *pKeyValueIn, uint8_t KeyLength)
{
  bool VerifyResult = false;
  char *pFunctionKeyValue = (char *)pKeyValueIn;

  if (pFunctionKeyValue != NULL)
  {
    for (uint8_t FunctionKeyNumber = 0; FunctionKeyNumber < END_OF_REVIEW; FunctionKeyNumber++)
    {
      if (strlen(FunctionPasswordLookupTable[FunctionKeyNumber]) == (KeyLength - 1))
      {
        if (strstr(pFunctionKeyValue, FunctionPasswordLookupTable[FunctionKeyNumber]) != NULL)
        {
          switch (FunctionKeyNumber)
          {
          case GETTING_NETWORK_QUALITY:
            VerifyResult = EventGetNetworkQuality();
            break;

          case SET_LOCK_ALWAYS_OPEN:
            VerifyResult = EventStartVerifyNormalOpenPermissionTask();
            break;

          case GET_BATTERY_PERCENTAGE:
            VerifyResult = EventPlayRemainingBatteryPercentage();
            break;

          case ENABLE_NETWORK_ATTACHMENT:
            VerifyResult = EventStartGetServerMessage();
            break;

          case DEVICE_START_FACTORY_SETTING:
            VerifyResult = EventStartKeyInAdminPasswordTask();
            break;

          case FORCE_DEVICE_RESET:
            VerifyResult = EventStartFactorySettingTask();
            break;
          }
        }
      }
    }
  }

  return VerifyResult;
}
#if _BOARD_TYPE_ == _EC01_BOARD_
// 用户鉴权
static void EventUserAuthenticationHandler(uint8_t KeyType, const void *pKeyValueIn, uint8_t NumberOfKey, uint8_t DoorAction)
{
  PRINT("[event_app] : EventUserAuthenticationHandler \r\n");
  if (NumberOfKey > 0)
  {
    uint32_t KeyToken, EndTimestamp = 0;
    uint8_t UnlockKeyType = 0, Result = 0;
    uint8_t AuthenticationKey[VALID_KEY_LENGTH] = {0};

    // if( EventGetDeviceActivationStatus() == false )
    // {
    //   PRINT("[authentication]: device is not activated.\r\n");
    //   return;
    // }

    {
      memset(AuthenticationKey, 0, VALID_KEY_LENGTH);

      PRINT("[authentication]: key type: %d, key length: %d. key value:", KeyType, NumberOfKey);
      for (uint8_t KeyIndex = 0; KeyIndex < VALID_KEY_LENGTH; KeyIndex++)
        PRINT("%02X ", ((uint8_t *)pKeyValueIn)[KeyIndex]);
      PRINT("\r\n");
      if ((GetIdentifyType() == 0))
      {
        EventPlayDoorUnlock();
        memcpy(AuthenticationKey, pKeyValueIn, VALID_KEY_LENGTH);
        EventWriteUserAuthenticationLogFile(LOG_PHYSICAL_CARD_NUMBER, AuthenticationKey, true);
        PRINT("Identify over GetIdentifyType %0d \r\n", GetIdentifyType());
        return;
      }
      else if (GetIdentifyType() == 4) // 不在有效期
      {
        PRINT("IdentifyType 4 \r\n");
        Result = USER_OUT_OF_DATE;
      }
      else
      {
        Result = EventUserAuthentication(KeyType, pKeyValueIn, NumberOfKey, &UnlockKeyType, &KeyToken, &EndTimestamp);

        if (KeyType != KEY_TYPE_CARD)
        {
          AuthenticationKey[0] = (uint8_t)((KeyToken & 0xFF000000) >> 24);
          AuthenticationKey[1] = (uint8_t)((KeyToken & 0x00FF0000) >> 16);
          AuthenticationKey[2] = (uint8_t)((KeyToken & 0x0000FF00) >> 8);
          AuthenticationKey[3] = (uint8_t)(KeyToken & 0x000000FF);
        }
        else
        {
          memcpy(AuthenticationKey, pKeyValueIn, VALID_KEY_LENGTH);
        }
      }
    }

    {
      switch (Result)
      {
      case USER_FORBIDDEN:
      {
        PRINT("[authentication]: cardholder disabled.\r\n");
        EventCardholderAuthenticationError(KeyType);
      }
      break;

      case USER_OUT_OF_DATE:
      {
        PRINT("[authentication]: no in the allowed time.\r\n");
        EventCardholderOutOfDate(KeyType);
      }
      break;

      case USER_AUTHENTICATION_SUCCESS:
      {
        if (EventGetLockedInEn() == true)
        {
          Result = USER_AUTHECTICATION_ERROR;

          PRINT("[authentication]: user is locked in.\r\n");
          EventDeviceAutiLock(KeyType);
        }
      }
      break;

      default:
      {
        PRINT("[authentication]: insufficient authority.\r\n");
        EventCardholderAuthenticationError(KeyType);
      }
      break;
      }

      uint8_t Flag = GetIoBoardFirmwareExistFlag();
      if (Flag == true)
      {
        // 提示用户正在ota
        PRINT("[event_app] :io board firmware is downloading, can not user auth!\r\n");
        return;
      }

      if (Result == USER_AUTHENTICATION_SUCCESS)
      {
        EventExecuteUnlockTask(UnlockKeyType, AuthenticationKey, EndTimestamp, DoorAction);
      }
      else
      {
        EventWriteUserAuthenticationLogFile(UnlockKeyType, AuthenticationKey, DoorAction);
      }
    }
  }
}

#else
static void EventUserAuthenticationHandler(uint8_t KeyType, const void *pKeyValueIn, uint8_t NumberOfKey, uint8_t DoorAction)
{
  if (NumberOfKey > 0)
  {
    uint32_t KeyToken, EndTimestamp = 0;
    uint8_t UnlockKeyType = 0, Result = 0;
    uint8_t AuthenticationKey[VALID_KEY_LENGTH] = {0};

    {
      memset(AuthenticationKey, 0, VALID_KEY_LENGTH);

      PRINT("[authentication]: key type: %d, key length: %d. key value:", KeyType, NumberOfKey);
      for (uint8_t KeyIndex = 0; KeyIndex < VALID_KEY_LENGTH; KeyIndex++)
        PRINT("%02X ", ((uint8_t *)pKeyValueIn)[KeyIndex]);
      PRINT("\r\n");

      Result = EventUserAuthentication(KeyType, pKeyValueIn, NumberOfKey, &UnlockKeyType, &KeyToken, &EndTimestamp);

      if (KeyType != KEY_TYPE_CARD)
      {
        AuthenticationKey[0] = (uint8_t)((KeyToken & 0xFF000000) >> 24);
        AuthenticationKey[1] = (uint8_t)((KeyToken & 0x00FF0000) >> 16);
        AuthenticationKey[2] = (uint8_t)((KeyToken & 0x0000FF00) >> 8);
        AuthenticationKey[3] = (uint8_t)(KeyToken & 0x000000FF);
      }
      else
      {
        memcpy(AuthenticationKey, pKeyValueIn, VALID_KEY_LENGTH);
      }
    }

    {
      switch (Result)
      {
      case USER_FORBIDDEN:
      {
        PRINT("[authentication]: cardholder disabled.\r\n");
        EventCardholderAuthenticationError(KeyType);
      }
      break;

      case USER_OUT_OF_DATE:
      {
        PRINT("[authentication]: no in the allowed time.\r\n");
        EventCardholderOutOfDate(KeyType);
      }
      break;

      case USER_AUTHENTICATION_SUCCESS:
      {
        if (EventGetLockedInEn() == true)
        {
          Result = USER_AUTHECTICATION_ERROR;

          PRINT("[authentication]: user is locked in.\r\n");
          EventDeviceAutiLock(KeyType);
        }
      }
      break;

      default:
      {
        PRINT("[authentication]: insufficient authority.\r\n");
        EventCardholderAuthenticationError(KeyType);
      }
      break;
      }

      if (Result == USER_AUTHENTICATION_SUCCESS)
      {
        EventExecuteUnlockTask(UnlockKeyType, AuthenticationKey, EndTimestamp, DoorAction);
      }
      else
      {
        EventWriteUserAuthenticationLogFile(UnlockKeyType, AuthenticationKey, false);
      }
    }
  }
}

#endif

static bool EventTaskScheduleTimeoutCallback(void)
{
  PRINT("[info]: task schedule timeout.\r\n");

  EventTaskScheduleTimerConfig(false);

  EventCenterStatusBit.TaskScheduleAction = TASK_SCHEDULE_TIMEOUT;
  EventStartTaskSchedule();

  return true;
}

static bool EventNetworkKeepLiveTimeoutCallback(void)
{
  PRINT("[info]: keep live timeout.\r\n");

  EventNetworkKeepLiveTimerConfig(false);
  uint32_t Interval = EventGetSearchTimeout();
  EventUpdateNetworkKeepLiveInterval(Interval);

  return true;
}

static bool EventGetServerMessageTimeoutCallback(void)
{
  EventSetStatusUpdateFlagBit(true);
  if (EventStartRequestServerInformationTask() != true)
  {
    EventStartUpdateBluetoothRadioTask();
  }

  uint32_t Interval = EventGetHeartbeatReportingInterval() * 60;
  EventUpdateGetServerMessageInterval(Interval);
  PRINT("[info]: get server message timeout, next wakeup time: %ds.\r\n", Interval);

  return true;
}

static bool EventAuthenticationErrorResetTimeoutCallback(void)
{
  EventCenterStatusBit.LockedStatusBit.NumberOfError = 0;

  EventResetAuthenticationErrorResetTimerConfig(false);
  PRINT("[info]: authentication error reset timeout.\r\n");

  return true;
}

static bool EventExitFactorySettingTaskCallback(void)
{
  PRINT("[info]: factory setting task exit.\r\n");

  EventStopRestoreFactoryTask();
  memset(&EventCenterStatusBit.DeviceResetStatus, 0, sizeof(DeviceResetStatusBit_t));

  return true;
}

static bool EventStartFactorySettingTaskCallback(void)
{
  PRINT("[info]: factory setting task start.\r\n");

  EventWriteDeviceFactorySettingLog();
  memset(&EventCenterStatusBit.DeviceResetStatus, 0, sizeof(DeviceResetStatusBit_t));
  EventDelayedStarRestoreFactoryTask(DEVICE_FACTORY_SETTING_EVENT_DELAY_EXECUTE_TIME * 1000);

  return true;
}

static bool EventExitBootloaderUpdateTaskCallback(void)
{
  bool UpdateResult = false;

  TaskScheduleNode_t Node = EventListFind(TaskScheduleNode, DEV_BOOTLOADER_UPDATA);
  if (Node != NULL)
  {
    FirmwareUpdateStatusBit_t FirmwareUpdateStatusBit = {0};

    memcpy(&FirmwareUpdateStatusBit, Node->AttachedParam.Param, sizeof(FirmwareUpdateStatusBit_t));
    if (FirmwareUpdateStatusBit.Status == FIRMWARE_UPDATE_STATUS_SUCCESS)
    {
      if (EventUpdateBackupBootloaderFirmware() == true)
      {
        UpdateResult = true;
      }
    }
  }

  if (UpdateResult == true)
  {
    PRINT("[info]: bootloader update success.\r\n");

    EventPlayBootloaderUpdateStatus(true);
    EventDelayedStartDeviceRebootTask(APP_FIRMWARE_UPDATE_DELAY_RESET_TIME * 1000);
  }
  else
  {
    PRINT("[info]: bootloader update failed.\r\n");

    EventPlayBootloaderUpdateStatus(false);
  }

  return true;
}

static bool EventStartBootloaderUpdateTaskCallback(void)
{
  PRINT("[info]: bootloader update task start.\r\n");
  return true;
}

static bool EventExitApplicationUpdateTaskCallback(void)
{
  PRINT("[info]: application update task exit.\r\n");

  EventBluetoothDisconnectFromTheHost();
  EventDelayedStartDeviceRebootTask(FIRMWARE_UPDATE_DELAY_RESET_TIME * 1000);

  return true;
}

static bool EventStartApplicationUpdateTaskCallback(void)
{
  PRINT("[info]: application update task start.\r\n");

  EventWriteFirmwareUpgradeLog();
  return true;
}

static bool EventExitRebootTaskCallback(void)
{
  PRINT("[info]: reboot task exit.\r\n");
  EventStopDeviceRebootTask();

  return true;
}

static bool EventStartRebootTaskCallback(void)
{
  PRINT("[info]: reboot task start.\r\n");

  EventDelayedStartDeviceRebootTask(DEVICE_RESET_EVENT_DELAY_EXECUTE_TIME * 1000);
  return true;
}

extern bool ElevatorQueryIoBoardsIsExistTask(uint8_t *Parm);
static uint8_t Data[1] = {1};
// tag: 自检完成，自检结束，自检结果
static bool EventExitSelftestTaskCallback(void)
{
  PRINT("[info]: self test task exit.\r\n");
  EventPlayExitDevSelfTest();
#if 1
  uint8_t Addr[MAC_ADDR_CODING_LENGTH] = {0};
  Addr[5] = 1;
  SetDestinMacAddress(Addr);
  ElevatorQueryIoBoardsIsExistTask(&Data[0]);
#endif
  EventEnableAllInterrupt();
  EventEnableRfidFunction();
  EventEnableKeyboardFunction();

  if (VerifyOnBoardDeviceOperatingStatus() == true)
  {
    if (EventGetDeviceInitializationFlagBit() != true)
    {
      EventSetDeviceInitializationFlagBit(true);

      EventWriteDeviceStartupLogFile();
      if (EventGetWhetherThereAreLogsToBePushed() == true)
      {
        EventSetStatusUpdateFlagBit(true);
        EventSetLogNeedToBeUploadedFlagBit(true);
      }

      if (EventGetDeviceActivationStatus() == true)
      {
        if (EventGetVoltagePercentage() > LOW_BATTERY_ALERT_THRESHOLD)
        {
          EventPlayStartup(); // 设备已安装，上电提示
          EventGetServerMessageTimerConfig(true);
          // 绿灯常亮
          PromptAuthenticationInstallSuccess();
        }
        else
        {
          EventPlayLowBattery();
        }
      }
      else
      {
        EventPlayDeviceNotAuthorized(); // 恢复出厂，没有权限，设备重新上电时的提示
      }
    }
  }
  else
  {
    uint8_t ErrorHintCount = 0;

    if (EventCenterStatusBit.SelfTestStatus.FailureIdent.FailureBit.Rfid == DEV_SELF_TEST_ERROR)
    {
      ErrorHintCount = RFID_DEV_SELF_TEST;
    }
    else if (EventCenterStatusBit.SelfTestStatus.FailureIdent.FailureBit.Keyboard == DEV_SELF_TEST_ERROR)
    {
      ErrorHintCount = KEYBOARD_DEV_SELF_TEST;
    }
    else if (EventCenterStatusBit.SelfTestStatus.FailureIdent.FailureBit.Safety == DEV_SELF_TEST_ERROR)
    {
      ErrorHintCount = SAFETY_MODULE_DEV_SELF_TEST;
    }
    else if (EventCenterStatusBit.SelfTestStatus.FailureIdent.FailureBit.Network == DEV_SELF_TEST_ERROR)
    {
      ErrorHintCount = NETWORK_MODULE_DEV_SELF_TEST;
    }

    EventPlaySelfTestError(ErrorHintCount);
  }

  EventStopDeviceSelfTestTask();

  return true;
}

static bool EventStartSelftestTaskCallback(void)
{
  PRINT("[info]: self test task start.\r\n");
  EventPlayStartDevSelfTest();

  EventDisableAllInterrupt();
  EventDisableRfidFunction();
  EventDisableKeyboardFunction();

  memset(&EventCenterStatusBit.SelfTestStatus, 0, sizeof(SelfTestStatusBit_t));
  EventDelayedStartDeviceSelfTestTask(SELF_TEST_STARTUP_DELAY_TIME * 1000);

  return true;
}

static bool EventExitKeyInAdminPasswordCallback(void)
{
  TaskScheduleNode_t Node = EventListFind(TaskScheduleNode, DEV_KEY_IN_ADMIN_PASSWORD);
  if (Node != NULL)
  {
    {
      PRINT("[info]: exit key in admin password.\r\n");

      EventPlayExitKeyEntry();
      EventEnableRfidFunction();
      EventKeyboardIntoSleepMode();
    }

    {
      VerifyAdminPasswordFormat_t VerifyAdminPasswordFormat = {0};

      memcpy(&VerifyAdminPasswordFormat, Node->AttachedParam.Param, sizeof(VerifyAdminPasswordFormat_t));
      if (VerifyAdminPasswordFormat.NumberOfKey > 0)
      {
        if (EventVerifyAdministratorPassword(VerifyAdminPasswordFormat.KeyValue, VerifyAdminPasswordFormat.NumberOfKey) == USER_AUTHENTICATION_SUCCESS)
        {
          EventStartFactorySettingTask();
        }
        else
        {
          EventPlayAudioOfAuthenticationFailure();
        }
      }
      else
      {
        EventPlayExitVerificationMode();
      }
    }
  }

  return true;
}

static bool EventStartKeyInAdminPasswordTaskCallback(void)
{
  PRINT("[info]: start key in admin password.\r\n");

  EventDisableRfidFunction();
  EventPlayStartUserTypedKey();
  EventStartKeyInAdminPasswordMode();
  EventPlayVerifyAdminPassword();

  return true;
}

static bool EventExitVerifyNormalOpenPermissionCallback(void)
{
  TaskScheduleNode_t Node = EventListFind(TaskScheduleNode, DEV_VERIFY_NORMAL_OPEN_PERMISSION);
  if (Node != NULL)
  {
    {
      PRINT("[info]: exit verify normal open permission mode.\r\n");

      EventPlayExitKeyEntry();
      EventKeyboardIntoSleepMode();
      EventSafetyModuleIntoPowerDown();

      EventEnableRfidFunction();
      EventEnableKeyboardFunction();
    }

    {
      VerifyKeyFormat_t VerifyKeyFormat = {0};
      memcpy(&VerifyKeyFormat, Node->AttachedParam.Param, sizeof(VerifyKeyFormat_t));

      if ((VerifyKeyFormat.KeyType != 0) && (VerifyKeyFormat.NumberOfKey != 0))
      {
        if ((VerifyKeyFormat.KeyType == KEY_TYPE_KEYBOARD) && (VerifyKeyFormat.NumberOfKey == 0))
        {
          EventPlayExitVerificationMode();
          return true;
        }

        {
          bool VerifyResult = false;
          uint8_t EventUnlockType = {0};

          if (EventUserAuthentication(VerifyKeyFormat.KeyType, VerifyKeyFormat.KeyValue, VerifyKeyFormat.NumberOfKey, &EventUnlockType, NULL, NULL) == USER_AUTHENTICATION_SUCCESS)
          {
            VerifyResult = true;
          }
          else
          {
            if (VerifyKeyFormat.KeyType == KEY_TYPE_KEYBOARD)
            {
              if (EventVerifyAdministratorPassword(VerifyKeyFormat.KeyValue, VerifyKeyFormat.NumberOfKey) == USER_AUTHENTICATION_SUCCESS)
              {
                VerifyResult = true;
                EventUnlockType = EVENT_UNLOCK_PASSWORD;

                memset(VerifyKeyFormat.KeyValue, PROTOCOL_DUMMY_CODING, TYPE_THE_LENGTH_OF_KEY);
              }
            }
          }

          if (VerifyResult == true)
          {
            uint8_t UnlockType = (EventGetNormalOpenFlagBit() != true) ? DOOR_ACTION_NORMAL_OPEN : DOOR_ACTION_LOCK;
            EventExecuteUnlockTask(EventUnlockType, VerifyKeyFormat.KeyValue, 0, UnlockType);
          }
          else
          {
            EventPlayAudioOfAuthenticationFailure();
          }
        }
      }
    }
  }

  return true;
}

static bool EventStartVerifyNormalOpenPermissionCallback(void)
{
  PRINT("[info]: start verify normal open permission.\r\n");

  EventStartExternalValidation();
  EventKeyboardIntoVerifyUserPermissionMode();

  EventPlayVerifyUserPermissions();
  return true;
}

static bool EventExitLocalRegisterTaskCallback(void)
{
  TaskScheduleNode_t Node = EventListFind(TaskScheduleNode, DEV_LOCAL_REGISTER);
  if (Node != NULL)
  {
    PRINT("[info]: local register task exit.\r\n");

    RegisterKeyInformation_t RegisterKeyInformation = {0};
    memcpy(&RegisterKeyInformation, Node->AttachedParam.Param, sizeof(RegisterKeyInformation_t));

    if (EventGetLocalRegisterKeyResult() == LOCAL_REGISTER_RESULT_WAIT_SAVE)
    {
      if ((RegisterKeyInformation.NumberOfKey > 0) && (RegisterKeyInformation.NumberOfKey <= USER_AUTHENTICATION_KEY_LENGTH))
      {
        RegisterResult_t CreateResult = EventCreateNewKey(&RegisterKeyInformation);
        switch (CreateResult)
        {
        case REGISTER_USER_CARDHOLDER_IS_FULL:
        {
          PRINT("[local register]: cardholder is full.\r\n");
          EventUpdateLocalRegisterKeyResult(LOCAL_REGISTER_RESULT_CARDHOLDER_IS_FULL);
        }
        break;

        case REGISTER_USER_KEY_ALREADY_EXISTS:
        {
          PRINT("[local register]: key already exists.\r\n");
          EventUpdateLocalRegisterKeyResult(LOCAL_REGISTER_RESULT_KEY_ALREADY_EXISTS);
        }
        break;

        case REGISTER_USER_SUCCESS:
        {
          PRINT("[local register]: success.\r\n");
          EventUpdateLocalRegisterKeyResult(LOCAL_REGISTER_RESULT_DONE);
        }
        break;

        case REGISTER_USER_SINGLE_USER_LIMIT:
        {
          PRINT("[local register]: single user limit.\r\n");
          EventUpdateLocalRegisterKeyResult(LOCAL_REGISTER_RESULT_SINGLE_USER_LIMIT);
        }
        break;

        default:
        {
          PRINT("[local register]: error.\r\n");
          EventUpdateLocalRegisterKeyResult(LOCAL_REGISTER_RESULT_ERROR);
        }
        break;
        }
      }
      else
      {
        EventUpdateLocalRegisterKeyResult(LOCAL_REGISTER_RESULT_USER_EXIT);
      }
    }
    else
    {
      if (EventGetLocalRegisterKeyResult() == LOCAL_REGISTER_RESULT_BUSY)
      {
        PRINT("[local register]: timeout.\r\n");
        EventUpdateLocalRegisterKeyResult(LOCAL_REGISTER_RESULT_ERROR);
      }
    }

    {
      EventPlayExitKeyEntry();
      EventRfidExitCurrectMode();
      EventKeyboardIntoSleepMode();

      EventEnableRfidFunction();
      EventEnableKeyboardFunction();

      switch (EventGetLocalRegisterKeyResult())
      {
      case LOCAL_REGISTER_RESULT_DONE:
        EventPlayLocalRegisterStatus(true);
        break;

      case LOCAL_REGISTER_RESULT_USER_EXIT:
        EventPlayExitLocalRegister();
        break;

      default:
        EventPlayLocalRegisterStatus(false);
        break;
      }
    }
  }

  return true;
}

static bool EventStartLocalRegisterTaskCallback(void)
{
  RegisterKeyInformation_t RegisterKeyInformation = {0};
  LocalRegisterResult_t TaskStartResult = LOCAL_REGISTER_RESULT_DEVICE_BUSY;

  TaskScheduleNode_t Node = EventListFind(TaskScheduleNode, DEV_LOCAL_REGISTER);
  if (Node != NULL)
  {
    memcpy(&RegisterKeyInformation, Node->AttachedParam.Param, sizeof(RegisterKeyInformation_t));

    switch (RegisterKeyInformation.AuthenticationType)
    {
    case KEY_TYPE_CARD:
    {
      if (EventStartRfidLocalRegister() == true)
      {
        TaskStartResult = LOCAL_REGISTER_RESULT_BUSY;

        EventStartKeyboardLocalRegisterExitListerTask();
      }
    }
    break;

    case KEY_TYPE_KEYBOARD:
    {
      if (EventStartKeyboardLocalRegister() == true)
      {
        TaskStartResult = LOCAL_REGISTER_RESULT_BUSY;

        EventDisableRfidFunction();
      }
    }
    break;

    case KEY_TYPE_FACE:
    case KEY_TYPE_FINGER:
    {
      if (EventStartSafetyLocalRegister() == true)
      {
        TaskStartResult = LOCAL_REGISTER_RESULT_BUSY;

        EventDisableRfidFunction();
        EventStartKeyboardLocalRegisterExitListerTask();
      }
    }
    break;

    default:
      TaskStartResult = LOCAL_REGISTER_RESULT_ERROR;
      break;
    }

    if (TaskStartResult == LOCAL_REGISTER_RESULT_BUSY)
    {
      PRINT("[info]: local register task start.\r\n");

      EventPlayStartLocalRegistration();
    }
    else
    {
      EventUpdateLocalRegisterKeyResult(TaskStartResult);
      EventExitLocalRegisterKeyTask(KEY_TYEP_UNKOWN, NULL, 0);
    }
  }

  return true;
}

static bool EventExitOnlineRegisterTaskCallback(void)
{
  PRINT("[info]: online register task exit.\r\n");

  TaskScheduleNode_t Node = EventListFind(TaskScheduleNode, DEV_ONLINE_REGISTER);
  if (Node != NULL)
  {
    EventPlayExitOnlineRegisterMode();

    OnlineRegisterInformation_t OnlineRegisterInformation = {0};
    memcpy(&OnlineRegisterInformation, Node->AttachedParam.Param, sizeof(OnlineRegisterInformation_t));

    RegisterResult_t RegisterResult = EventGetOnlineRegisterResult();

    if (RegisterResult == REGISTER_USER_SUCCESS_WAIT_SAVE)
    {
      RegisterResult = EventCreateNewKey(&OnlineRegisterInformation.KeyInformation);

      if (RegisterResult != REGISTER_USER_SUCCESS)
      {
        EventSafetyModuleDeleteSpecificKey(OnlineRegisterInformation.KeyInformation.AuthenticationKey);
      }
    }
    else
    {
      if (RegisterResult == REGISTER_USER_START)
      {
        RegisterResult = REGISTER_USER_TIMEOUT;
      }
    }

    {
      {
        if (RegisterResult == REGISTER_USER_SUCCESS)
        {
          EventCenterStatusBit.OnlineRegisterStatus.FileReceiveSuccessNumber++;
        }
        else
        {
          EventCenterStatusBit.OnlineRegisterStatus.FileReceiveFailNumber++;
        }

        if ((OnlineRegisterInformation.NumberOfRemainingFile == 0) || (RegisterResult == REGISTER_USER_TIMEOUT))
        {
          EventPlayRegisterUserCount(EventCenterStatusBit.OnlineRegisterStatus.FileReceiveSuccessNumber, EventCenterStatusBit.OnlineRegisterStatus.FileReceiveFailNumber);
          memset(&EventCenterStatusBit.OnlineRegisterStatus, 0, sizeof(OnlineRegisterStatusBit_t));
        }
      }

      if (EventDetermineWhetherTheOnlineRegistrationMethodIsHostPush(OnlineRegisterInformation.Source) == true)
      {
        OnlineRegisterResultFormat_t OnlineRegisterResultFormat = {0};

        OnlineRegisterResultFormat.Result = RegisterResult;
        memcpy(&OnlineRegisterResultFormat.Information, &OnlineRegisterInformation.KeyInformation, sizeof(RegisterKeyInformation_t));
        EventStartPushOnlineRegisterStatusTask(&OnlineRegisterResultFormat);
      }
    }
  }

  return true;
}

static bool EventStartOnlineRegisterTaskCallback(void)
{
  PRINT("[info]: online register task start.\r\n");

  TaskScheduleNode_t Node = EventListFind(TaskScheduleNode, DEV_ONLINE_REGISTER);
  if (Node != NULL)
  {
    if (EventGetOnlineRegisterResult() == REGISTER_USER_IDLE)
    {
      EventPlayInitiateDocumentReceipt();
    }

    EventPlayStartOnlineRegisterUser();
    EventUpdateOnlineRegisterResult(REGISTER_USER_START);
  }

  return true;
}

static bool EventExitRequestServerInformationTaskCallback(void)
{
  PRINT("[info]: request server information task exit.\r\n");

  TaskScheduleNode_t Node = EventListFind(TaskScheduleNode, DEV_REQUEST_SERVER_MESSAGE);
  if (Node != NULL)
  {
    EventMessageSendStatus_t EventMessageSendStatus = {0};
    memcpy(&EventMessageSendStatus, Node->AttachedParam.Param, sizeof(EventMessageSendStatus_t));

    PRINT("[info]: request server information task execute result: %02X.\r\n", EventMessageSendStatus.Status);
    EventPlayNetAttachEnd();
    EventResetNetworkStatus();
    EventForceEndMessageSend();
    EventPlayNetAttachStatus(EventMessageSendStatus.Status);

#if _NETWOK_MODLE_TYPE_ == _ML307R_MODLE_
    if (EventMessageSendStatus.Status != SEND_STATUS_DONE)
    {
      EventSetNetworkConnectStatus(NETWORK_CONNECT_ERROR);
    }
#endif
  }

  return true;
}

static bool EventStartRequestServerInformationTaskCallback(void)
{
  PRINT("[info]: request server information task start.\r\n");

  EventPlayNetAttachStart();
  EventSendHeartbeatToServer();

  return true;
}

static bool EventExitActivelyRequestServerMessageTaskCallback(void)
{
  PRINT("[info]: actively request server message task exit.\r\n");

  TaskScheduleNode_t Node = EventListFind(TaskScheduleNode, DEV_ACTIVELY_REQUEST_SERVER_MESSAGE);
  if (Node != NULL)
  {
    EventMessageSendStatus_t EventMessageSendStatus = {0};
    memcpy(&EventMessageSendStatus, Node->AttachedParam.Param, sizeof(EventMessageSendStatus_t));

    PRINT("[info]: actively request server message task execute result: %02X.\r\n", EventMessageSendStatus.Status);

    EventPlayNetAttachEnd();
    EventResetNetworkStatus();
    EventForceEndMessageSend();
    EventPlayNetAttachStatus(EventMessageSendStatus.Status);

#if _NETWOK_MODLE_TYPE_ == _ML307R_MODLE_
    if (EventMessageSendStatus.Status != SEND_STATUS_DONE)
    {
      EventSetNetworkConnectStatus(NETWORK_CONNECT_ERROR);
    }
#endif
  }

  return true;
}

static bool EventStartActivelyRequestServerMessageTaskCallback(void)
{
  PRINT("[info]: actively request server message task start.\r\n");

  EventPlayNetAttachStart();
  EventActivePushHeartbeatToHost();

  return true;
}

static bool EventExitInformationReportingTaskCallback(void)
{
  PRINT("[info]: information reporting task exit.\r\n");

  TaskScheduleNode_t Node = EventListFind(TaskScheduleNode, DEV_INFORMATION_REPORTING);
  if (Node != NULL)
  {
    EventMessageSendStatus_t EventMessageSendStatus = {0};
    memcpy(&EventMessageSendStatus, Node->AttachedParam.Param, sizeof(EventMessageSendStatus_t));

    PRINT("[info]: information reporting task execute result: %02X.\r\n", EventMessageSendStatus.Status);

    EventPlayNetAttachEnd();
    EventResetNetworkStatus();
    EventForceEndMessageSend();
    EventPlayNetAttachStatus(EventMessageSendStatus.Status);

#if _NETWOK_MODLE_TYPE_ == _ML307R_MODLE_
    if (EventMessageSendStatus.Status != SEND_STATUS_DONE)
    {
      EventSetNetworkConnectStatus(NETWORK_CONNECT_ERROR);
    }
#endif
  }

  return true;
}

static bool EventStartInformationReportingTaskCallback(void)
{
  PRINT("[info]: information reporting task start.\r\n");

  TaskScheduleNode_t Node = EventListFind(TaskScheduleNode, DEV_INFORMATION_REPORTING);
  if (Node != NULL)
  {
    EventPlayNetAttachStart();

    PushEventFormat_t PushEventFormat = {0};
    memcpy(&PushEventFormat, Node->AttachedParam.Param, sizeof(PushEventFormat_t));

    EventRealTimePushOfUnlockEvent(PushEventFormat.LogId, PushEventFormat.LogType, PushEventFormat.AttaParameter);
  }

  return true;
}

static bool EventExitAlarmReportingTaskCallback(void)
{
  PRINT("[info]: alarm reporting task exit.\r\n");

  TaskScheduleNode_t Node = EventListFind(TaskScheduleNode, DEV_ALARM_EVENT_REPORTING);
  if (Node != NULL)
  {
    EventMessageSendStatus_t EventMessageSendStatus = {0};
    memcpy(&EventMessageSendStatus, Node->AttachedParam.Param, sizeof(EventMessageSendStatus_t));

    PRINT("[info]: alarm reporting task execute result: %02X.\r\n", EventMessageSendStatus.Status);

    EventPlayNetAttachEnd();
    EventResetNetworkStatus();
    EventForceEndMessageSend();
    EventPlayNetAttachStatus(EventMessageSendStatus.Status);

#if _NETWOK_MODLE_TYPE_ == _ML307R_MODLE_
    if (EventMessageSendStatus.Status != SEND_STATUS_DONE)
    {
      EventSetNetworkConnectStatus(NETWORK_CONNECT_ERROR);
    }
#endif
  }

  return true;
}

static bool EventStartAlarmReportingTaskCallback(void)
{
  PRINT("[info]: alarm reporting task start.\r\n");

  TaskScheduleNode_t Node = EventListFind(TaskScheduleNode, DEV_ALARM_EVENT_REPORTING);
  if (Node != NULL)
  {
    EventPlayNetAttachStart();

    PushAlarmEventFormat_t PushAlarmEventFormat = {0};
    memcpy(&PushAlarmEventFormat, Node->AttachedParam.Param, sizeof(PushAlarmEventFormat_t));

    EventRealTimePushOfAlarmEvent(PushAlarmEventFormat.LogId, PushAlarmEventFormat.LogType, PushAlarmEventFormat.TiggerEn);
  }

  return true;
}

bool EventExitPushOnlineRegisterStatusTaskCallback(void)
{
  PRINT("[info]: push online register status task exit.\r\n");

  TaskScheduleNode_t Node = EventListFind(TaskScheduleNode, DEV_PUSH_STATUS_ONLINE_REGISTER_RESULT);
  if (Node != NULL)
  {
    EventMessageSendStatus_t EventMessageSendStatus = {0};
    memcpy(&EventMessageSendStatus, Node->AttachedParam.Param, sizeof(EventMessageSendStatus_t));

    PRINT("[info]: push online register status task execute result: %02X.\r\n", EventMessageSendStatus.Status);

    EventPlayNetAttachEnd();
    EventResetNetworkStatus();
    EventForceEndMessageSend();
    EventPlayNetAttachStatus(EventMessageSendStatus.Status);

#if _NETWOK_MODLE_TYPE_ == _ML307R_MODLE_
    if (EventMessageSendStatus.Status != SEND_STATUS_DONE)
    {
      EventNetworkDisconnect();
    }
#endif
  }

  return true;
}

bool EventStartPushOnlineRegisterStatusTaskCallback(void)
{
  TaskScheduleNode_t Node = EventListFind(TaskScheduleNode, DEV_PUSH_STATUS_ONLINE_REGISTER_RESULT);
  if (Node != NULL)
  {
    OnlineRegisterResultFormat_t OnlineRegisterResultFormat = {0};

    memcpy(&OnlineRegisterResultFormat, Node->AttachedParam.Param, sizeof(OnlineRegisterResultFormat_t));
    EventUploadOnlineRegisterResult(&OnlineRegisterResultFormat.Information, OnlineRegisterResultFormat.Result);

    EventPlayNetAttachStart();
  }

  return true;
}

static bool EventExitDoorUnlockTaskCallback(void)
{
  TaskScheduleNode_t Node = EventListFind(TaskScheduleNode, DEV_UNLOCK);
  if (Node != NULL)
  {
    UnlockingMethodFormat_t UnlockingMethodFormat = {0};
    memcpy(&UnlockingMethodFormat, CurrectTaskScheduleNode->AttachedParam.Param, sizeof(UnlockingMethodFormat_t));

    if (UnlockingMethodFormat.UnlockingMethod != DOOR_ACTION_NORMAL_OPEN)
    {
      if (EventGetObliqueTongueTiggerEn() == true)
        return false;

      PRINT("[info]: door unlock task exit.\r\n");

      EventPlayDoorLock();
      EventExecuteDoorLock();

      if (EventDetermineIfLockOffPromptIsRequired(UnlockingMethodFormat.KeyType) == true)
      {
        if (EventGetVoltagePercentage() <= LOW_BATTERY_ALERT_THRESHOLD)
        {
          EventPlayLowBattery();
        }
      }
    }
  }

  return true;
}

static bool EventStartDoorUnlockTaskCallback(void)
{
  PRINT("[info]: door unlock task start.\r\n");

  uint32_t AuthorizationExpirationTime = 0;
  uint32_t NowTimestamp = EventGetCurrectTimestamp();
  UnlockingMethodFormat_t UnlockingMethodFormat = {0};

  EventCenterStatusBit.LockedStatusBit.NumberOfError = 0;
  memcpy(&UnlockingMethodFormat, CurrectTaskScheduleNode->AttachedParam.Param, sizeof(UnlockingMethodFormat_t));

  switch (UnlockingMethodFormat.UnlockingMethod)
  {
  case DOOR_ACTION_UNLOCK:
  case DOOR_ACTION_NORMAL_OPEN:
  {
    if (EventGetAuthorizationExpirationEn() != true)
    {
      EventSetDeviceLastActionTime();

      AuthorizationExpirationTime = UnlockingMethodFormat.AuthorizationExpirationTime[0] << 24;
      AuthorizationExpirationTime |= UnlockingMethodFormat.AuthorizationExpirationTime[1] << 16;
      AuthorizationExpirationTime |= UnlockingMethodFormat.AuthorizationExpirationTime[2] << 8;
      AuthorizationExpirationTime |= UnlockingMethodFormat.AuthorizationExpirationTime[3];

      // 执行开锁并提示相关状态
      if (UnlockingMethodFormat.UnlockingMethod == DOOR_ACTION_UNLOCK)
      {
        PRINT("[info]: door unlock.\r\n");

        EventPlayDoorUnlock();
        EventExecuteDoorUnlock();

        uint16_t LogId = EventWriteUserAuthenticationLogFile(UnlockingMethodFormat.KeyType, UnlockingMethodFormat.KeyValue, true);
        EventStartInformationReportingTask(LogId, UnlockingMethodFormat.KeyType, UnlockingMethodFormat.KeyValue);
      }
      else
      {
        PRINT("[info]: door normal open.\r\n");

        EventPlayDoorNormallyOpen();
        EventExecuteDoorNormalOpen();

        EventSetNormalOpenFlagBit(true);
        uint16_t LogId = EventWriteNormalOpenTiggerStatusLogFile(true);
        EventStartAlarmReportingTask(LogId, EVENT_ALARM_NORMAL_OPEN, true);
      }

      // 提示续约时间
      if (EventGetDayBroadcastContorlEn() == true)
      {
        if (((NowTimestamp != 0) && (NowTimestamp != 0xFFFFFFFF)) && ((AuthorizationExpirationTime != 0) && (AuthorizationExpirationTime != 0xFFFFFFFF)))
        {
          if (AuthorizationExpirationTime > NowTimestamp)
          {
            uint32_t TimeRemaining = (uint32_t)((AuthorizationExpirationTime - NowTimestamp) / 86400) + 1;

            if (TimeRemaining <= EventGetBroadcastRemainingDays())
            {
              EventPlayExpirationReminder(TimeRemaining);
            }
          }
        }
      }
    }
    else
    {
      EventPlayLicenseExpiredSoundEffects();
    }
  }
  break;

  default:
  {
    EventPlayUserExecutelockAction();

    if (EventGetNormalOpenFlagBit() == true)
    {
      EventSetNormalOpenFlagBit(false);
      uint16_t LogId = EventWriteNormalOpenTiggerStatusLogFile(false);
      EventStartAlarmReportingTask(LogId, EVENT_ALARM_NORMAL_OPEN, false);
    }
  }
  break;
  }

  return true;
}

static bool EventExitDoorLockTaskCallback(void)
{
  PRINT("[info]: door lock task exit.\r\n");

  EventPlayExitDeviceLockedState();
  return true;
}

static bool EventStartDoorLockTaskCallback(void)
{
  PRINT("[info]: door lock task start.\r\n");

  EventPlayDeviceLocked();
  return true;
}

static bool EventExitReadCardTaskCallback(void)
{
  PRINT("[info]: read card task exit.\r\n");

  EventEnableRfidFunction();
  EventRfidExitCurrectMode();
  EventEnableKeyboardFunction();

  TaskScheduleNode_t Node = EventListFind(TaskScheduleNode, DEV_READ_CARD);
#if (((_BOARD_TYPE_ & _DA01_BOARD_) != _DA01_BOARD_)) // && ((_BOARD_TYPE_ & _EC01_BOARD_)!= _EC01_BOARD_))
  if (Node != NULL)
  {
    VerifyKeyFormat_t VerifyKeyFormat = {0};
    memcpy(&VerifyKeyFormat, Node->AttachedParam.Param, sizeof(VerifyKeyFormat_t));

    PRINT("[info]: verify key type: %02X, number of key: %d.\r\n", VerifyKeyFormat.KeyType, VerifyKeyFormat.NumberOfKey);
    PRINT("[info]: verify key value: ");
    for (uint8_t i = 0; i < VerifyKeyFormat.NumberOfKey; i++)
      PRINT("%02X", VerifyKeyFormat.KeyValue[i]);
    PRINT("\r\n");
    PRINT(" Write  card log\r\n");

    EventUserAuthenticationHandler(VerifyKeyFormat.KeyType, VerifyKeyFormat.KeyValue, VerifyKeyFormat.NumberOfKey, DOOR_ACTION_UNLOCK);
  }
#endif

  return true;
}

static bool EventStartReadCardTaskCallback(void)
{
  PRINT("[info]: read card task start.\r\n");

  EventStartReadCardTask();
  EventDisableKeyboardFunction();

  return true;
}

static bool EventExitExternalModuleVerifyTaskCallback(void)
{
  PRINT("[info]: external module verify task exit.\r\n");

  EventEnableRfidFunction();
  EventSafetyModuleIntoPowerDown();
  EventPlayExitSafetyModuleAuthentication();

  TaskScheduleNode_t Node = EventListFind(TaskScheduleNode, DEV_SAFETY_AUTHENTICATION);
  if (Node != NULL)
  {
    VerifyKeyFormat_t VerifyKeyFormat = {0};
    memcpy(&VerifyKeyFormat, Node->AttachedParam.Param, sizeof(VerifyKeyFormat_t));

    EventUserAuthenticationHandler(VerifyKeyFormat.KeyType, VerifyKeyFormat.KeyValue, VerifyKeyFormat.NumberOfKey, DOOR_ACTION_UNLOCK);
  }

  return true;
}

static bool EventStartExternalModuleVerifyTaskCallback(void)
{
  PRINT("[info]: external module verify task start.\r\n");

  EventDisableRfidFunction();
  EventStartExternalValidation();
  EventPlayStartSafetyModuleAuthentication();

  return true;
}

static bool EventExitKeyboardKeyscanfTaskCallback(void)
{
  PRINT("[info]: keyboard keyscanf task exit.\r\n");

  EventPlayExitKeyEntry();
  EventEnableRfidFunction();
  EventKeyboardIntoSleepMode();

  TaskScheduleNode_t Node = EventListFind(TaskScheduleNode, DEV_KEYSCANF);
  if (Node != NULL)
  {
    VerifyKeyFormat_t VerifyKeyFormat = {0};
    memcpy(&VerifyKeyFormat, Node->AttachedParam.Param, sizeof(VerifyKeyFormat_t));

    if (EventVerifyIfFunctionPassword(VerifyKeyFormat.KeyValue, VerifyKeyFormat.NumberOfKey) != true)
    {
      EventUserAuthenticationHandler(VerifyKeyFormat.KeyType, VerifyKeyFormat.KeyValue, VerifyKeyFormat.NumberOfKey, DOOR_ACTION_UNLOCK);
    }
  }

  return true;
}

static bool EventStartKeyboardKeyscanfTaskCallback(void)
{
  PRINT("[info]: keyboard keyscanf task start.\r\n");

  EventDisableRfidFunction();
  EventPlayStartUserTypedKey();
  EventKeyboardIntoStandbyMode();

  return true;
}

static bool EventExitLockedInTipTaskCallback(void)
{
  PRINT("[info]: locked in tip task exit.\r\n");
  return true;
}

static bool EventStartLockedInTipTaskCallback(void)
{
  EventPlayLockedInAlarmTigger();
  PRINT("[info]: locked in tip task start.\r\n");

  return true;
}

static bool EventExitFalseLockedTipTaskCallback(void)
{
  PRINT("[info]: false locked tip task exit.\r\n");

  return true;
}

static bool EventStartFalseLockedTipTaskCallback(void)
{
  EventPlayFalseLockAlarmTigger();
  PRINT("[info]: false locked tip task start.\r\n");

  return true;
}

static bool EventExitPickLockedTipTaskCallback(void)
{
  PRINT("[info]: pick locked tip task exit.\r\n");

  return true;
}

static bool EventStartPickLockedTipTaskCallback(void)
{
  EventPlayAutiPickingRecovered();
  PRINT("[info]: pick locked tip task start.\r\n");

  return true;
}

static bool EventExitKeyInTipTaskCallback(void)
{
  PRINT("[info]: key in tip task exit.\r\n");

  return true;
}

static bool EventStartKeyInTipCallback(void)
{
  PRINT("[info]: key in tip task start.\r\n");

  EventPlayKeyInstall();
  return true;
}

static bool EventExitWirelessWakeupTaskCallback(void)
{
  PRINT("[info]: wireless wakeup task exit.\r\n");
  return true;
}

static bool EventStartWirelessWakeupTaskCallback(void)
{
  PRINT("[info]: wireless wakeup task start.\r\n");
  return true;
}

static bool EventExitUpdateBluetoothRadioCallback(void)
{
  PRINT("[info]: exit update bluetooth radio.\r\n");

  EventSetStatusUpdateFlagBit(false);
  return true;
}

static bool EventStartUpdateBluetoothRadioCallback(void)
{
  PRINT("[info]: start update bluetooth radio.\r\n");

  EventBatteryStartGetPercentageOfElectricity();
  EventUpdateBluetoothRadio();

  return true;
}

static bool EventExitStandbyTaskCallback(void)
{
  PRINT("[info]: standby task exit.\r\n");

  EventPlayExitStandbyMode();
  return true;
}

static uint8_t OtaTimeoutCount = 0; // ota超时计数
#define THREE_MIN_COUNT 90 //3分钟
bool SetOtaTimeoutCount(uint8_t Count)
{
  OtaTimeoutCount = Count;
  return true;
}

static bool EventStartStandbyTaskCallback(void)
{
  PRINT("999999999999999999999\r\n");
  {
    PRINT("[info]: standby task start. OtaTimeoutCount = %d\r\n", OtaTimeoutCount);

    if (GetIoBoardFirmwareExistFlag() == true)
    {
      OtaTimeoutCount++;
      if (OtaTimeoutCount > THREE_MIN_COUNT)
      {
        PRINT("[info] : ota timeout.\r\n");
        OtaTimeoutCount = 0;
        SetIoBoardFirmwareExistFlag(false);
        PromptIntoIoBoardUpdataFirmware();
      }
    }
    else
    {
      // EventPlayIntoStandbyMode();
      OtaTimeoutCount = 0;
    }
  }

  if (EventCheckIfTheIndicatorLightIsOn() != true)
  {
#if ((_BOARD_TYPE_ & _DA01_BOARD_) != _DA01_BOARD_ || ((_BOARD_TYPE_ & _EC01_BOARD_) != _EC01_BOARD_))
    // if (EventGetNetworkKeepLiveTimerConfigEn() == true)
    {
      PRINT("[info]: standby task start.\r\n");
      EventPlayIntoStandbyMode();
    }
#endif
  }

  return true;
}

static void EventInitialisingTaskSchedule(void)
{
  TaskScheduleNode = EventListCreate();
}

static void EventDeleteCurrectTask(TaskScheduleNode_t Node)
{
  EventListErase(Node);
}

static bool EventResetTaskRuntime(SystemAction_t TaskLevel)
{
  if (CurrectTaskScheduleNode->AttachedParam.Level == TaskLevel)
  {
    TaskScheduleTimeNode.AccruedTime = 0;
    return true;
  }

  return false;
}

static bool EventUpdateTargetActionAttachedParam(SystemAction_t TaskLevel, const void *pDataIn, uint8_t SizeIn)
{
  if (pDataIn != NULL)
  {
    if ((SizeIn > 0) && (SizeIn <= EVENT_TASK_ATTACHED_PARAM_SIZE))
    {
      TaskScheduleNode_t Node = EventListFind(TaskScheduleNode, TaskLevel);
      if (Node != NULL)
      {
        memcpy(Node->AttachedParam.Param, pDataIn, SizeIn);
        return true;
      }
    }
  }

  return false;
}

static TaskScheduleNode_t EventGetMixPriorityTask(void)
{
  TaskScheduleNode_t MixListNode = NULL;
  TaskScheduleNode_t TmpListNode = TaskScheduleNode->NextItem;

  if (TmpListNode != TaskScheduleNode)
  {
    MixListNode = TmpListNode;

    while (TmpListNode != TaskScheduleNode)
    {
      if (MixListNode->AttachedParam.Level > TmpListNode->AttachedParam.Level)
      {
        MixListNode = TmpListNode;
      }

      TmpListNode = TmpListNode->NextItem;
    }
  }

  return MixListNode;
}

static bool EventMarkTaskExecuteComplete(SystemAction_t TaskLevel)
{
  if (CurrectTaskScheduleNode != NULL)
  {
    if (CurrectTaskScheduleNode->AttachedParam.Level == TaskLevel)
    {
      EventCenterStatusBit.TaskScheduleAction = TASK_SCHEDULE_DELETE;
      EventStartTaskSchedule();

      return true;
    }
  }

  return false;
}

static bool EventMarkSystemNewAction(SystemAction_t TaskLevel, TaskExecuteCallback_t pTaskExecute, TaskExitCallback_t pTaskExit, uint16_t Timeout, uint8_t AutoDestroy, const void *pDataIn, uint8_t SizeIn, bool EventCacheEn)
{
  if ((pTaskExecute != NULL) && (pTaskExit != NULL) && (SizeIn <= EVENT_TASK_ATTACHED_PARAM_SIZE))
  {
    if ((EventJudgeWhetherTheNewActionIsValid(TaskLevel) == true) || (EventCacheEn == true))
    {
      TaskAttachedParam_t TaskAttachedParam = {0};

      {
        memset(&TaskAttachedParam, 0, sizeof(TaskAttachedParam_t));

        TaskAttachedParam.Level = TaskLevel;
        TaskAttachedParam.Timeout = Timeout;
        TaskAttachedParam.AutoDestroy = AutoDestroy;

        TaskAttachedParam.Exit = pTaskExit;
        TaskAttachedParam.Execute = pTaskExecute;
        if ((SizeIn > 0) && (pDataIn != NULL))
        {
          memcpy(TaskAttachedParam.Param, pDataIn, SizeIn);
        }
      }

      if (EventListPushFront(TaskScheduleNode, &TaskAttachedParam) == true)
      {
        if (CurrectTaskScheduleNode == NULL)
        {
          PRINT("[info]: get new task.\r\n");

          EventCenterStatusBit.TaskScheduleAction = TASK_SCHEDULE_GET;
          EventStartTaskSchedule();
        }
        else
        {
          if (CurrectTaskScheduleNode->AttachedParam.Level > TaskLevel)
          {
            PRINT("[info]: delete task.\r\n");

            EventCenterStatusBit.TaskScheduleAction = TASK_SCHEDULE_DELETE;
            EventStartTaskSchedule();
          }
        }

        return true;
      }
    }
  }

  return false;
}

static void EventCreateTaskScheduleTimer(void)
{
  bool CreateResult = EventAddNewTimedTask(&TaskScheduleTimeNode, 0, TIMED_TASK_HIGH_LEVEL, EventTaskScheduleTimeoutCallback, false);
  PRINT("[info]: create task schedule, result: %d.\r\n", CreateResult);
}

static void EventCreateNetworkKeepLiveTimer(void)
{
  uint32_t Interval = EventGetSearchTimeout();
  bool CreateResult = EventAddNewTimedTask(&NetworkKeepLiveTimeNode, Interval, TIMED_TASK_LOW_LEVEL, EventNetworkKeepLiveTimeoutCallback, false);
  PRINT("[info]: create network keep live, result: %d.\r\n", CreateResult);
}

static void EventCreateGetServerMessageTimer(void)
{
  bool CreateResult = EventAddNewTimedTask(&GetServerMessageTimeNode, 2, TIMED_TASK_LOW_LEVEL, EventGetServerMessageTimeoutCallback, false);
  PRINT("[info]: create get server message, result: %d.\r\n", CreateResult);
}

static void EventCreateAuthenticationErrorResetTimer(void)
{
  uint32_t Interval = AUTHENTICATION_FAILURE_RESET_TIME * 60;
  bool CreateResult = EventAddNewTimedTask(&AuthenticationErrResetTimeNode, Interval, TIMED_TASK_LOW_LEVEL, EventAuthenticationErrorResetTimeoutCallback, false);
  PRINT("[info]: create authentication error reset, result: %d.\r\n", CreateResult);
}

static bool EventJudgeIfAuthFailureLimitReached(uint8_t KeyType)
{
  if (EventCenterStatusBit.LockedStatusBit.NumberOfError >= (NUMBER_OF_FALSE_TIGGERS - 1))
  {
    PRINT("[alarm]: device is locked, unlock time: %d.\r\n", EventCenterStatusBit.LockedStatusBit.EndTimestamp);

    EventCenterStatusBit.LockedStatusBit.LockedEn = true;
    EventCenterStatusBit.LockedStatusBit.NumberOfError = 0;
    EventCenterStatusBit.LockedStatusBit.EndTimestamp = EventGetCurrectTimestamp() + EventGetSystemLockedTime();

    EventPlayAudioOfDeviceLocked();
    EventResetAuthenticationErrorResetTimerConfig(false);

    return true;
  }
  else
  {
    if (EventGetTragetTypeAuthenticationErrorEn(KeyType) == true)
    {
      (EventCenterStatusBit.LockedStatusBit.NumberOfError == 0) ? EventResetAuthenticationErrorResetTimerConfig(true) : EventResetAuthenticationErrorResetTimer();

      EventCenterStatusBit.LockedStatusBit.NumberOfError++;
      PRINT("[info]: %ld attempts remaining.\r\n", NUMBER_OF_FALSE_TIGGERS - EventCenterStatusBit.LockedStatusBit.NumberOfError);
    }
  }

  return false;
}

static bool VerifyOnBoardDeviceOperatingStatus(void)
{
  if (EventCenterStatusBit.SelfTestStatus.FailureIdent.FailureBit.Rfid == DEV_SELF_TEST_ERROR)
    return false;

  if (EventCenterStatusBit.SelfTestStatus.FailureIdent.FailureBit.Safety == DEV_SELF_TEST_ERROR)
    return false;

  if (EventCenterStatusBit.SelfTestStatus.FailureIdent.FailureBit.Network == DEV_SELF_TEST_ERROR)
    return false;

  if (EventCenterStatusBit.SelfTestStatus.FailureIdent.FailureBit.Keyboard == DEV_SELF_TEST_ERROR)
    return false;

  return true;
}

static DevGetSelfTestResult_t EventObtainTheTypeOfSensorForSelfTest(SelfTestOrder_t CurrentOrder, SelfTestOrder_t *pNextOrder)
{
  SelfTestOrder_t SelfTestStatus;
  DevGetSelfTestResult_t GetResult = DEV_GET_SELF_TEST_RETRY;

  switch (CurrentOrder)
  {
  case SELF_TEST_WAIT:
  {
    SelfTestStatus = RFID_DEV_SELF_TEST;

    if (EventGetRfidFunctionEnable() == true)
    {
      GetResult = DEV_GET_SELF_TEST_SUCCESS;
    }
  }
  break;

  case RFID_DEV_SELF_TEST:
  {
    SelfTestStatus = KEYBOARD_DEV_SELF_TEST;

    if (EventGetKeyboardFunctionEnable() == true)
    {
      GetResult = DEV_GET_SELF_TEST_SUCCESS;
    }
  }
  break;

  case KEYBOARD_DEV_SELF_TEST:
  {
    SelfTestStatus = SAFETY_MODULE_DEV_SELF_TEST;

    if (EventGetSafetyFunctionEnable() == true)
    {
      GetResult = DEV_GET_SELF_TEST_SUCCESS;
    }
  }
  break;

  case SAFETY_MODULE_DEV_SELF_TEST:
  {
    SelfTestStatus = NETWORK_MODULE_DEV_SELF_TEST;

    if (EventGetNetwokFunctionEnable() == true)
    {
      GetResult = DEV_GET_SELF_TEST_SUCCESS;
    }
  }
  break;

  default:
  {
    GetResult = DEV_GET_SELF_TEST_DONE;
    SelfTestStatus = ALL_MODULE_SELF_TEST_SUCCESS;
  }
  break;
  }

  if (pNextOrder != NULL)
  {
    *pNextOrder = SelfTestStatus;
  }

  return GetResult;
}

static GetDeviceResetResult_t EventObtainTheTypeOfSensorForReset(DeviceResetStep_t CurrentStep, DeviceResetStep_t *pNextStep)
{
  DeviceResetStep_t DeviceResetStep;
  GetDeviceResetResult_t GetResult = GET_RESET_RESULT_RETRY;

  switch (CurrentStep)
  {
  case DEVICE_RESET_WAIT:
  {
    DeviceResetStep = DELETE_SAFETY_MODULE_DATA;

    if (EventGetSafetyFunctionEnable() == true)
    {
      GetResult = GET_RESET_RESULT_SUCCESS;
    }
  }
  break;

  case DELETE_SAFETY_MODULE_DATA:
  {
    DeviceResetStep = DELETE_NETWORK_MODULE_DATA;

    if (EventGetNetwokFunctionEnable() == true)
    {
      GetResult = GET_RESET_RESULT_SUCCESS;
    }
  }
  break;

  default:
  {
    GetResult = GET_RESET_RESULT_DONE;
    DeviceResetStep = ALL_MODULE_DELETED_OVER_SUCCESS;
  }
  break;
  }

  if (pNextStep != NULL)
  {
    *pNextStep = DeviceResetStep;
  }

  return GetResult;
}

static SelfTestStartResult_t EventInitiateModuleSpecificSelfTestTasks(SelfTestOrder_t ModuleType)
{
  SelfTestStartResult_t TaskStartResult = SELF_TEST_NO_SUPPORT;

  switch (ModuleType)
  {
  case RFID_DEV_SELF_TEST:
  {
    TaskStartResult = EventStartRfidSelfTest();
    PRINT("[self-test]: start rfid device self-test, result: %d.\r\n", TaskStartResult);
  }
  break;

  case KEYBOARD_DEV_SELF_TEST:
  {
    TaskStartResult = EventStartKeyboardSelfTest();
    PRINT("[self-test]: start keyboard device self-test, result: %d.\r\n", TaskStartResult);
  }
  break;

  case SAFETY_MODULE_DEV_SELF_TEST:
  {
    TaskStartResult = EventStartSafetySelfTest();
    PRINT("[self-test]: start safety device self-test, result: %d.\r\n", TaskStartResult);
  }
  break;

  case NETWORK_MODULE_DEV_SELF_TEST:
  {
    TaskStartResult = EventStartNetworkSelfTest();
    PRINT("[self-test]: start network device self-test, result: %d.\r\n", TaskStartResult);
  }
  break;

  default:
    break;
  }

  return TaskStartResult;
}

static ResetStartResult_t EventInitiateModuleSpecificResetTask(DeviceResetStep_t ModuleType)
{
  ResetStartResult_t TaskStartResult = false;

  switch (ModuleType)
  {
  case DELETE_SAFETY_MODULE_DATA:
  {
    TaskStartResult = EventStartSafetyReset();
    PRINT("[info]: start safety device reset, result: %d.\r\n", TaskStartResult);
  }
  break;

  case DELETE_NETWORK_MODULE_DATA:
  {
    TaskStartResult = EventStartNetworkReset();
    PRINT("[info]: start netwok device reset, result: %d.\r\n", TaskStartResult);
  }
  break;

  default:
    break;
  }

  return TaskStartResult;
}

static void EventTaskScheduledCallback(void)
{
  switch (EventCenterStatusBit.TaskScheduleAction)
  {
  case TASK_SCHEDULE_DELETE:
  case TASK_SCHEDULE_TIMEOUT:
  {
    EventTaskScheduleTimerConfig(false);

    if (CurrectTaskScheduleNode != NULL)
    {
      if (CurrectTaskScheduleNode->AttachedParam.Exit != NULL)
      {
        if (CurrectTaskScheduleNode->AttachedParam.Exit() != true)
        {
          EventUpdateTaskScheduleInterval(CurrectTaskScheduleNode->AttachedParam.Timeout);
          EventTaskScheduleTimerConfig(true);
        }
        else
        {
          PRINT("[info]: task: %d deletion successful.\r\n", CurrectTaskScheduleNode->AttachedParam.Level);
          EventDeleteCurrectTask(CurrectTaskScheduleNode);

          EventCenterStatusBit.TaskScheduleAction = TASK_SCHEDULE_GET;
          EventStartTaskSchedule();
        }
      }
      else
      {
        EventDeleteCurrectTask(CurrectTaskScheduleNode);

        EventCenterStatusBit.TaskScheduleAction = TASK_SCHEDULE_GET;
        EventStartTaskSchedule();
      }
    }
    else
    {
      EventCenterStatusBit.TaskScheduleAction = TASK_SCHEDULE_GET;
      EventStartTaskSchedule();
    }
  }
  break;

  default:
  {
    CurrectTaskScheduleNode = EventGetMixPriorityTask();
    if (CurrectTaskScheduleNode != NULL)
    {
      if (CurrectTaskScheduleNode->AttachedParam.Execute != NULL)
      {
        CurrectTaskScheduleNode->AttachedParam.Execute();

        {
          EventSetDeviceWakeupFlagBit(true);
          PRINT("[info]: device wakeup.\r\n");
        }

        if (CurrectTaskScheduleNode->AttachedParam.AutoDestroy == true)
        {
          PRINT("[info]: task will be deleted after execution.\r\n");

          EventCenterStatusBit.TaskScheduleAction = TASK_SCHEDULE_DELETE;
          EventStartTaskSchedule();
        }
        else
        {
          PRINT("[info]: task is executing with a timeout of: %ds.\r\n", CurrectTaskScheduleNode->AttachedParam.Timeout);

          EventUpdateTaskScheduleInterval(CurrectTaskScheduleNode->AttachedParam.Timeout);
          EventTaskScheduleTimerConfig(true);
        }
      }
      else
      {
        PRINT("[error]: task execute function is null.\r\n");

        EventCenterStatusBit.TaskScheduleAction = TASK_SCHEDULE_DELETE;
        EventStartTaskSchedule();
      }
    }
    else
    {
#if (((_BOARD_TYPE_ & _DA01_BOARD_) != _DA01_BOARD_) && ((_BOARD_TYPE_ & _EC01_BOARD_) != _EC01_BOARD_))
      bool DeviceSleepFlag = true;

      if ((EventGetNetworkKeepLiveTimerConfigEn() == true) ||
          (EventCheckIfTheIndicatorLightIsOn() == true) ||
          (EventGetBluetoothConnectFlagBit() == true) ||
          (EventGetVoicePlayBusyFlagBit() == true) ||
          (EventGetSafatyModuleBusyEn() == true))
      {
        if (EventStartStadnbyTask() == true)
        {
          DeviceSleepFlag = false;
        }
      }
      else
      {
        if (EventGetStatusUpdateFlagBit() == true)
        {
          if (EventStartUpdateBluetoothRadioTask() == true)
          {
            DeviceSleepFlag = false;
          }
        }
      }

      if (DeviceSleepFlag == true)
      {
        PRINT("[info]: device enters sleep mode.\r\n");

        EventActionBeforeSleep();
        EventSetDeviceWakeupFlagBit(false);
      }

#else
      EventStartStadnbyTask();
#endif
    }
  }
  break;
  }
}

static void EventScheduledTaskCallback(void)
{
  TimedListNode_t TmpListNode = TimedListNode;

  while (TmpListNode != NULL)
  {
    if (TmpListNode->En == true)
    {
      if (TmpListNode->TriggerTime > 0)
      {
        TmpListNode->AccruedTime++;
        if (TmpListNode->AccruedTime >= TmpListNode->TriggerTime)
        {
          TmpListNode->AccruedTime = 0;

          if (TmpListNode->ScheduledTask != NULL)
          {
            TmpListNode->ScheduledTask();
          }
        }
      }
    }

    TmpListNode = TmpListNode->PreviousItem;
  }

  EventDelayedStartScheduleTask(TIMED_TASK_INTERVAL_WAKEUP_TIME * 1000);
}

static void EventDeviceRebootCallback(void)
{
  EventSoftwareReset();
}

static void EventRestoreFactoryCallback(void)
{
  GetDeviceResetResult_t Result = GET_RESET_RESULT_ERR;

  switch (EventCenterStatusBit.DeviceResetStatus.Status)
  {
  case DEVICE_RESET_IDLE:
  {
    PRINT("[reset]: start factory reset.\r\n");

    EventStartRestoreFactoryTaskNoWait();
    EventCenterStatusBit.DeviceResetStatus.Status = GETTING_RESET_DEVICE;
  }
  break;

  case GETTING_RESET_DEVICE:
  {
    EventResetTaskRuntime(DEV_FACTORY_SETTING);

    Result = EventObtainTheTypeOfSensorForReset(EventCenterStatusBit.DeviceResetStatus.Step, &EventCenterStatusBit.DeviceResetStatus.Step);
    if ((Result == GET_RESET_RESULT_RETRY) || (Result == GET_RESET_RESULT_SUCCESS))
    {
      if (Result == GET_RESET_RESULT_SUCCESS)
      {
        EventCenterStatusBit.DeviceResetStatus.Status = INITIATE_DEVICE_RESET;
      }

      EventStartRestoreFactoryTaskNoWait();
    }
    else
    {
      EventStartRestoreFactoryTaskNoWait();
      EventCenterStatusBit.DeviceResetStatus.Status = RESET_ALL_MODULES_COMPLETE;
    }
  }
  break;

  case INITIATE_DEVICE_RESET:
  {
    ResetStartResult_t StartResult = EventInitiateModuleSpecificResetTask(EventCenterStatusBit.DeviceResetStatus.Step);

    if (StartResult == RESET_START_SUCCESS)
    {
      PRINT("[reset]: wait for target module to return result.\r\n");

      EventCenterStatusBit.DeviceResetStatus.Status = WAIT_DEVICE_RESET_TIMEOUT;
      EventDelayedStarRestoreFactoryTask(WAIT_DEVICE_RESET_RESULT_TIMEOUT * 1000);
    }
    else if (StartResult == SELF_TEST_NO_SUPPORT)
    {
      PRINT("[reset]: device not support.\r\n");

      EventStartRestoreFactoryTaskNoWait();
      EventCenterStatusBit.DeviceResetStatus.Status = GETTING_RESET_DEVICE;
    }
    else
    {
      PRINT("[reset]: retrieve reset device type.\r\n");

      EventStartRestoreFactoryTaskNoWait();
      EventCenterStatusBit.DeviceResetStatus.Status = GETTING_RESET_DEVICE;
    }
  }
  break;

  case WAIT_DEVICE_RESET_TIMEOUT:
  {
    PRINT("[reset]: waiting for return result timeout.\r\n");

    EventStartRestoreFactoryTaskNoWait();
    EventCenterStatusBit.DeviceResetStatus.Status = RESET_ALL_MODULES_COMPLETE;
  }
  break;

  case RESET_ALL_MODULES_COMPLETE:
  {
    PRINT("[reset]: all module reset success.\r\n");

    EventDeleteAllCardholder();
    EventRestoreDefaultUserParameters();

    EventStartDeviceRebootTask();
    EventExitFactorySettingTask();
    EventCenterStatusBit.DeviceResetStatus.Status = DEVICE_RESET_IDLE;
    EventCenterStatusBit.DeviceResetStatus.Step = ALL_MODULE_DELETED_OVER_SUCCESS;
  }
  break;

  default:
  {
    PRINT("[reset]: software failure.\r\n");

    EventStartRestoreFactoryTaskNoWait();
    EventCenterStatusBit.DeviceResetStatus.Status = RESET_ALL_MODULES_COMPLETE;
  }
  break;
  }
}

static void SystemFirmwarwUpdateCallback(void)
{
  EventFlagFirmwareUpdateEnable();
  EventStartDeviceRebootTask();
}

static uint8_t Data2 = 0;
static uint8_t MainBoard_Selftest_Fg=1;
extern bool NetworkSetBoardSelfTestModeTask(uint8_t *Parm);
static void EventDeviceSelfTestCallback(void)
{
  DevGetSelfTestResult_t Result = DEV_GET_SELF_TEST_ERR;

  switch (EventCenterStatusBit.SelfTestStatus.Status)
  {
  case SELF_TEST_IDLE:
  {
    PRINT("[self-test]: start test.\r\n");

    EventCenterStatusBit.SelfTestStatus.FailureIdent.Ident = 0;
    EventCenterStatusBit.SelfTestStatus.FailureIdent.FailureBit.Rfid = DEV_SELF_TEST_NO_SUPPORT;
    EventCenterStatusBit.SelfTestStatus.FailureIdent.FailureBit.Safety = DEV_SELF_TEST_NO_SUPPORT;
    EventCenterStatusBit.SelfTestStatus.FailureIdent.FailureBit.Network = DEV_SELF_TEST_NO_SUPPORT;
    EventCenterStatusBit.SelfTestStatus.FailureIdent.FailureBit.Keyboard = DEV_SELF_TEST_NO_SUPPORT;

    // 启动主板任务
    if(MainBoard_Selftest_Fg)
    {
      MainBoard_Selftest_Fg=0;
    }
    else 
    {
      NetworkSetBoardSelfTestModeTask(&Data2);
    }
    EventStartDeviceSelfTestTaskNoWait();
    EventCenterStatusBit.SelfTestStatus.Status = OBTAIN_SELF_TEST_EQUIPMENT;
  }
  break;

  case OBTAIN_SELF_TEST_EQUIPMENT:
  {
    EventResetTaskRuntime(DEV_SELF_TEST);

    Result = EventObtainTheTypeOfSensorForSelfTest(EventCenterStatusBit.SelfTestStatus.Order, &EventCenterStatusBit.SelfTestStatus.Order);
    if ((Result == DEV_GET_SELF_TEST_RETRY) || (Result == DEV_GET_SELF_TEST_SUCCESS))
    {
      if (Result == DEV_GET_SELF_TEST_SUCCESS)
      {
        EventCenterStatusBit.SelfTestStatus.Status = START_MODULE_SELF_TEST_TASK;
      }

      EventStartDeviceSelfTestTaskNoWait();
    }
    else
    {
      EventStartDeviceSelfTestTaskNoWait();
      EventCenterStatusBit.SelfTestStatus.Status = SELF_TEST_COMPLETE;
    }
  }
  break;

  case START_MODULE_SELF_TEST_TASK:
  {
    SelfTestStartResult_t StartResult = EventInitiateModuleSpecificSelfTestTasks(EventCenterStatusBit.SelfTestStatus.Order);
    if (StartResult == SELF_TEST_START_SUCCESS)
    {
      PRINT("[self-test]: wait for target module to return result.\r\n");

      EventCenterStatusBit.SelfTestStatus.Status = WAIT_DEVICE_SELF_TEST_TIMEOUT;
      EventDelayedStartDeviceSelfTestTask(WAIT_DEVICE_SELF_TEST_RESULT_TIMEOUT * 1000);
    }
    else if (StartResult == SELF_TEST_NO_SUPPORT)
    {
      PRINT("[self-test]: device not support.\r\n");

      EventStartDeviceSelfTestTaskNoWait();
      EventCenterStatusBit.SelfTestStatus.Status = OBTAIN_SELF_TEST_EQUIPMENT;
    }
    else
    {
      PRINT("[self-test]: retrieve self-test device type.\r\n");

      EventStartDeviceSelfTestTaskNoWait();
      EventCenterStatusBit.SelfTestStatus.Status = OBTAIN_SELF_TEST_EQUIPMENT;
    }
  }
  break;

  case WAIT_DEVICE_SELF_TEST_TIMEOUT:
  {
    PRINT("[self-test]: waiting for return result timeout.\r\n");

    EventStartDeviceSelfTestTaskNoWait();
    EventCenterStatusBit.SelfTestStatus.Status = OBTAIN_SELF_TEST_EQUIPMENT;
  }
  break;

  case SELF_TEST_COMPLETE:
  {
    PRINT("[self-test]: all module self-test success.\r\n");
    EventCenterStatusBit.SelfTestStatus.Order = ALL_MODULE_SELF_TEST_SUCCESS;

    EventExitDeviceSelfTestTask();
  }
  break;

  default:
  {
    PRINT("[self-test]: software failure.\r\n");

    EventStartDeviceSelfTestTaskNoWait();
    EventCenterStatusBit.SelfTestStatus.Status = SELF_TEST_COMPLETE;
  }
  break;
  }
}

void EventGetServerMessageTimerConfig(bool En)
{
  GetServerMessageTimeNode.En = En;
}

void EventTaskScheduleTimerConfig(bool En)
{
  TaskScheduleTimeNode.En = En;
}

void EventNetworkKeepLiveTimerConfig(bool En)
{
  NetworkKeepLiveTimeNode.En = En;
}

void EventResetAuthenticationErrorResetTimerConfig(bool En)
{
  AuthenticationErrResetTimeNode.En = En;
}

bool EventGetServerMessageTimerConfigEn(void)
{
  return GetServerMessageTimeNode.En;
}

bool EventGetTaskScheduleTimerConfigEn(void)
{
  return TaskScheduleTimeNode.En;
}

bool EventGetNetworkKeepLiveTimerConfigEn(void)
{
  return NetworkKeepLiveTimeNode.En;
}

bool EventGetResetAuthenticationErrorResetEn(void)
{
  return AuthenticationErrResetTimeNode.En;
}

void EventResetAccumulatedTimeOfGetServerMessage(void)
{
  GetServerMessageTimeNode.AccruedTime = 0;
}

void EventResetAccumulatedTimeOfNetworkKeepLive(void)
{
  NetworkKeepLiveTimeNode.AccruedTime = 0;
}

void EventResetAccumulatedTimeOfTaskSchedule(void)
{
  TaskScheduleTimeNode.AccruedTime = 0;
}

void EventResetAuthenticationErrorResetTimer(void)
{
  AuthenticationErrResetTimeNode.AccruedTime = 0;
}

void EventUpdateGetServerMessageInterval(uint32_t Interval)
{
  GetServerMessageTimeNode.AccruedTime = 0;
  GetServerMessageTimeNode.TriggerTime = Interval;
}

void EventUpdateTaskScheduleInterval(uint32_t Interval)
{
  TaskScheduleTimeNode.AccruedTime = 0;
  TaskScheduleTimeNode.TriggerTime = Interval;
}

void EventUpdateNetworkKeepLiveInterval(uint32_t Interval)
{
  NetworkKeepLiveTimeNode.AccruedTime = 0;
  NetworkKeepLiveTimeNode.TriggerTime = Interval;
}

void EventUpdateAuthenticationErrorResetInterval(uint32_t Interval)
{
  AuthenticationErrResetTimeNode.AccruedTime = 0;
  AuthenticationErrResetTimeNode.TriggerTime = Interval;
}

uint8_t EventGetLocalRegisterKeyStep(void)
{
  return EventCenterStatusBit.LocalRegisterStatusBit.Step;
}

void EventSetLocalRegisterKeyStep(uint8_t Step)
{
  PRINT("[local register]: new step %d.\r\n", Step);
  EventCenterStatusBit.LocalRegisterStatusBit.Step = Step;
}

uint8_t EventGetLocalRegisterKeyResult(void)
{
  return EventCenterStatusBit.LocalRegisterStatusBit.Result;
}

void EventUpdateLocalRegisterKeyResult(LocalRegisterResult_t Result)
{
  PRINT("[local register]: new result %d.\r\n", Result);
  EventCenterStatusBit.LocalRegisterStatusBit.Result = Result;
}

RegisterResult_t EventGetOnlineRegisterResult(void)
{
  return EventCenterStatusBit.OnlineRegisterStatus.Result;
}

void EventUpdateOnlineRegisterResult(RegisterResult_t Result)
{
  PRINT("[online register]: new result %d.\r\n", Result);
  EventCenterStatusBit.OnlineRegisterStatus.Result = Result;
}

bool EventStartDeviceRebootTask(void)
{
  return EventMarkSystemNewAction(DEV_REBBOOT, EventStartRebootTaskCallback, EventExitRebootTaskCallback, NORMAL_TASK_RUN_TIMEOUT, false, NULL, 0, false);
}

bool EventExitRebootTask(void)
{
  return EventMarkTaskExecuteComplete(DEV_REBBOOT);
}

bool EventStartFactorySettingTask(void)
{
  return EventMarkSystemNewAction(DEV_FACTORY_SETTING, EventStartFactorySettingTaskCallback, EventExitFactorySettingTaskCallback, NORMAL_TASK_RUN_TIMEOUT, false, NULL, 0, false);
}

bool EventExitFactorySettingTask(void)
{
  return EventMarkTaskExecuteComplete(DEV_FACTORY_SETTING);
}

bool EventGetFirmwareDataInformation(uint32_t *pCrcValueOut, uint32_t *pFileSizeOut)
{
  TaskScheduleNode_t Node = EventListFind(TaskScheduleNode, DEV_BOOTLOADER_UPDATA);
  if (Node != NULL)
  {
    FirmwareUpdateStatusBit_t FirmwareUpdateStatusBit = {0};

    memcpy(&FirmwareUpdateStatusBit, Node->AttachedParam.Param, sizeof(FirmwareUpdateStatusBit_t));

    if (pCrcValueOut != NULL)
    {
      *pCrcValueOut = FirmwareUpdateStatusBit.CrcValue;
    }

    if (pFileSizeOut != NULL)
    {
      *pFileSizeOut = FirmwareUpdateStatusBit.FileSize;
    }

    return true;
  }

  return true;
}

bool EventStartBootloaderUpdateTask(uint32_t CrcValue, uint32_t FileSize)
{
  FirmwareUpdateStatusBit_t FirmwareUpdateStatusBit = {0};

  FirmwareUpdateStatusBit.CrcValue = CrcValue;
  FirmwareUpdateStatusBit.FileSize = FileSize;
  FirmwareUpdateStatusBit.Status = FIRMWARE_UPDATE_STATUS_START;

  return EventMarkSystemNewAction(DEV_BOOTLOADER_UPDATA, EventStartBootloaderUpdateTaskCallback, EventExitBootloaderUpdateTaskCallback, BOOTLOADER_FIRMWARE_UPDATE_TASK_RUN_TIMEOUT, false, &FirmwareUpdateStatusBit, sizeof(FirmwareUpdateStatusBit_t), false);
}

bool EventExitBootloaderUpdateTask(FirmwareUpdateStatus_t UpdateStatus)
{
  TaskScheduleNode_t Node = EventListFind(TaskScheduleNode, DEV_BOOTLOADER_UPDATA);
  if (Node != NULL)
  {
    FirmwareUpdateStatusBit_t FirmwareUpdateStatusBit = {0};
    memcpy(&FirmwareUpdateStatusBit, Node->AttachedParam.Param, sizeof(FirmwareUpdateStatusBit_t));

    FirmwareUpdateStatusBit.Status = UpdateStatus;
    memcpy(Node->AttachedParam.Param, &FirmwareUpdateStatusBit, sizeof(FirmwareUpdateStatusBit_t));

    return EventMarkTaskExecuteComplete(DEV_BOOTLOADER_UPDATA);
  }

  return false;
}

bool EventStartApplicationUpdateTask(void)
{
  return EventMarkSystemNewAction(DEV_APPLCATION_UPDATA, EventStartApplicationUpdateTaskCallback, EventExitApplicationUpdateTaskCallback, FIRMWARE_UPDATE_TASK_RUN_TIMEOUT, false, NULL, 0, false);
}

bool EventExitApplicationUpdateTask(void)
{
  return EventMarkTaskExecuteComplete(DEV_APPLCATION_UPDATA);
}

bool EventStartDeviceSelfTestTask(void)
{
  return EventMarkSystemNewAction(DEV_SELF_TEST, EventStartSelftestTaskCallback, EventExitSelftestTaskCallback, NORMAL_TASK_RUN_TIMEOUT, false, NULL, 0, false);
}

bool EventExitDeviceSelfTestTask(void)
{
  return EventMarkTaskExecuteComplete(DEV_SELF_TEST);
}

bool EventStartKeyInAdminPasswordTask(void)
{
  if (EventGetDeviceActivationStatus() == true)
  {
    if (EventMarkSystemNewAction(DEV_KEY_IN_ADMIN_PASSWORD, EventStartKeyInAdminPasswordTaskCallback, EventExitKeyInAdminPasswordCallback, EventUserActionTimeout(), false, NULL, 0, false) != true)
    {
      EventPlayEquipmentBusyStatus();
    }
  }
  else
  {
    EventPlayDeviceNotAuthorized();
  }

  return true;
}

bool EventExitKeyInAdminPasswordTask(const void *pPasswordIn, uint8_t NumberOfPassword)
{
  TaskScheduleNode_t Node = EventListFind(TaskScheduleNode, DEV_KEY_IN_ADMIN_PASSWORD);
  if (Node != NULL)
  {
    if (NumberOfPassword <= TYPE_THE_LENGTH_OF_KEY)
    {
      VerifyAdminPasswordFormat_t VerifyAdminPasswordFormat = {0};

      VerifyAdminPasswordFormat.NumberOfKey = NumberOfPassword;
      if ((NumberOfPassword > 0) && (pPasswordIn != NULL))
      {
        memcpy(VerifyAdminPasswordFormat.KeyValue, pPasswordIn, NumberOfPassword);
      }

      memcpy(Node->AttachedParam.Param, &VerifyAdminPasswordFormat, sizeof(VerifyAdminPasswordFormat_t));
      return EventMarkTaskExecuteComplete(DEV_KEY_IN_ADMIN_PASSWORD);
    }
  }

  return false;
}

bool EventStartVerifyNormalOpenPermissionTask(void)
{
  if (EventGetDeviceActivationStatus() == true)
  {
    if (EventMarkSystemNewAction(DEV_VERIFY_NORMAL_OPEN_PERMISSION, EventStartVerifyNormalOpenPermissionCallback, EventExitVerifyNormalOpenPermissionCallback, EventUserActionTimeout(), false, NULL, 0, false) != true)
    {
      EventPlayEquipmentBusyStatus();
    }
  }
  else
  {
    EventPlayDeviceNotAuthorized();
  }

  return true;
}

bool EventExitVerifyNormalOpenPermissionTask(uint8_t KeyType, const void *pKeyIn, uint8_t NumberOfKeyIn)
{
  TaskScheduleNode_t Node = EventListFind(TaskScheduleNode, DEV_VERIFY_NORMAL_OPEN_PERMISSION);
  if (Node != NULL)
  {
    if (NumberOfKeyIn <= TYPE_THE_LENGTH_OF_KEY)
    {
      VerifyKeyFormat_t VerifyKeyFormat = {0};

      VerifyKeyFormat.KeyType = KeyType;
      VerifyKeyFormat.NumberOfKey = NumberOfKeyIn;
      if ((NumberOfKeyIn > 0) && (pKeyIn != NULL))
      {
        memcpy(VerifyKeyFormat.KeyValue, pKeyIn, NumberOfKeyIn);
      }

      memcpy(Node->AttachedParam.Param, &VerifyKeyFormat, sizeof(VerifyKeyFormat_t));
      return EventMarkTaskExecuteComplete(DEV_VERIFY_NORMAL_OPEN_PERMISSION);
    }
  }

  return false;
}

bool EventExitRequestServerInformationTask(uint8_t EventMessageSendStatus)
{
#if _NETWOK_FUNCTION_ENABLE_
  TaskScheduleNode_t Node = EventListFind(TaskScheduleNode, DEV_REQUEST_SERVER_MESSAGE);
  if (Node != NULL)
  {
    EventMessageSendStatus_t MessageSendStatus = {0};

    MessageSendStatus.Status = EventMessageSendStatus;
    memcpy(Node->AttachedParam.Param, &MessageSendStatus, sizeof(EventMessageSendStatus_t));
    return EventMarkTaskExecuteComplete(DEV_REQUEST_SERVER_MESSAGE);
  }
#endif

  return false;
}

bool EventStartRequestServerInformationTask(void)
{
#if _NETWOK_FUNCTION_ENABLE_
  if (EventCenterStatusBit.SelfTestStatus.FailureIdent.FailureBit.Network == DEV_SELF_TEST_SUCCESS)
  {
    if (EventGetDeviceActivationStatus() == true)
    {
      if (EventGetVoltagePercentage() >= EVENT_LOW_VOLTAGE_THRESHOLD)
      {
        if (EventMarkSystemNewAction(DEV_REQUEST_SERVER_MESSAGE, EventStartRequestServerInformationTaskCallback, EventExitRequestServerInformationTaskCallback, MESSAGE_SEND_TIMEOUT, false, NULL, 0, true) == true)
        {
          EventSetNetworkConnectStatus(NETWORK_CLOSED);
          return true;
        }
      }
    }
  }
#endif

  return false;
}

bool EventExitActivelyRequestServerTask(uint8_t EventMessageSendStatus)
{
#if _NETWOK_FUNCTION_ENABLE_
  TaskScheduleNode_t Node = EventListFind(TaskScheduleNode, DEV_ACTIVELY_REQUEST_SERVER_MESSAGE);
  if (Node != NULL)
  {
    EventMessageSendStatus_t MessageSendStatus = {0};

    MessageSendStatus.Status = EventMessageSendStatus;
    memcpy(Node->AttachedParam.Param, &MessageSendStatus, sizeof(EventMessageSendStatus_t));
    return EventMarkTaskExecuteComplete(DEV_ACTIVELY_REQUEST_SERVER_MESSAGE);
  }
#endif

  return false;
}

bool EventStartActivelyRequestServerTask(void)
{
#if _NETWOK_FUNCTION_ENABLE_
  if (EventMarkSystemNewAction(DEV_ACTIVELY_REQUEST_SERVER_MESSAGE, EventStartActivelyRequestServerMessageTaskCallback, EventExitActivelyRequestServerMessageTaskCallback, MESSAGE_SEND_TIMEOUT, false, NULL, 0, true) == true)
  {
    EventSetNetworkConnectStatus(NETWORK_CLOSED);
    return true;
  }
#endif

  return false;
}

bool EventExitPushOnlineRegisterStatusTask(uint8_t EventMessageSendStatus)
{
#if _NETWOK_FUNCTION_ENABLE_
  TaskScheduleNode_t Node = EventListFind(TaskScheduleNode, DEV_PUSH_STATUS_ONLINE_REGISTER_RESULT);
  if (Node != NULL)
  {
    EventMessageSendStatus_t MessageSendStatus = {0};

    MessageSendStatus.Status = EventMessageSendStatus;
    memcpy(Node->AttachedParam.Param, &MessageSendStatus, sizeof(EventMessageSendStatus_t));
    return EventMarkTaskExecuteComplete(DEV_PUSH_STATUS_ONLINE_REGISTER_RESULT);
  }
#endif

  return false;
}

bool EventStartPushOnlineRegisterStatusTask(OnlineRegisterResultFormat_t *pRegisterInformationIn)
{
#if _NETWOK_FUNCTION_ENABLE_
  if (pRegisterInformationIn != NULL)
  {
    if (EventCenterStatusBit.SelfTestStatus.FailureIdent.FailureBit.Network == DEV_SELF_TEST_SUCCESS)
    {
      if (EventGetDeviceActivationStatus() == true)
      {
        if (EventGetVoltagePercentage() > LOW_BATTERY_ALERT_THRESHOLD)
        {
          if (EventMarkSystemNewAction(DEV_PUSH_STATUS_ONLINE_REGISTER_RESULT, EventStartPushOnlineRegisterStatusTaskCallback, EventExitPushOnlineRegisterStatusTaskCallback, MESSAGE_SEND_TIMEOUT, false, pRegisterInformationIn, sizeof(OnlineRegisterResultFormat_t), false) == true)
            return true;
        }
      }
    }
  }
#endif

  return false;
}

bool EventExitInformationReportingTask(uint8_t EventMessageSendStatus)
{
#if _NETWOK_FUNCTION_ENABLE_
  TaskScheduleNode_t Node = EventListFind(TaskScheduleNode, DEV_INFORMATION_REPORTING);
  if (Node != NULL)
  {
    EventMessageSendStatus_t MessageSendStatus = {0};

    MessageSendStatus.Status = EventMessageSendStatus;
    memcpy(Node->AttachedParam.Param, &MessageSendStatus, sizeof(EventMessageSendStatus_t));
    return EventMarkTaskExecuteComplete(DEV_INFORMATION_REPORTING);
  }
#endif

  return false;
}

bool EventStartInformationReportingTask(uint16_t LogId, uint8_t LogType, const void *pAuthenticationCodeIn)
{
#if _NETWOK_FUNCTION_ENABLE_
  if (pAuthenticationCodeIn != NULL)
  {
    if (EventCenterStatusBit.SelfTestStatus.FailureIdent.FailureBit.Network == DEV_SELF_TEST_SUCCESS)
    {
      if (EventGetVoltagePercentage() > LOW_BATTERY_ALERT_THRESHOLD)
      {
        if (EventGetNetworkConnectStatus() != NETWORK_CONNECT_ERROR)
        {
          if (EventGetDeviceActivationStatus() == true)
          {
            PushEventFormat_t PushEventFormat = {0};

            PushEventFormat.LogId = LogId;
            PushEventFormat.LogType = LogType;
            memcpy(&PushEventFormat.AttaParameter, pAuthenticationCodeIn, USER_AUTHENTICATION_KEY_LENGTH);
            return EventMarkSystemNewAction(DEV_INFORMATION_REPORTING, EventStartInformationReportingTaskCallback, EventExitInformationReportingTaskCallback, MESSAGE_SEND_TIMEOUT, false, &PushEventFormat, sizeof(PushEventFormat_t), true);
          }
          else
          {
            PRINT("[report]: device not authorized.\r\n");
          }
        }
      }
    }
  }
#endif

  return false;
}

bool EventExitAlarmReportingTask(uint8_t EventMessageSendStatus)
{
#if _NETWOK_FUNCTION_ENABLE_
  TaskScheduleNode_t Node = EventListFind(TaskScheduleNode, DEV_ALARM_EVENT_REPORTING);
  if (Node != NULL)
  {
    EventMessageSendStatus_t MessageSendStatus = {0};

    MessageSendStatus.Status = EventMessageSendStatus;
    memcpy(Node->AttachedParam.Param, &MessageSendStatus, sizeof(EventMessageSendStatus_t));
    return EventMarkTaskExecuteComplete(DEV_ALARM_EVENT_REPORTING);
  }
#endif

  return false;
}

bool EventStartAlarmReportingTask(uint16_t LogId, uint8_t LogType, uint8_t TiggerEn)
{
#if _NETWOK_FUNCTION_ENABLE_
  if (EventCenterStatusBit.SelfTestStatus.FailureIdent.FailureBit.Network == DEV_SELF_TEST_SUCCESS)
  {
    if (EventGetVoltagePercentage() > LOW_BATTERY_ALERT_THRESHOLD)
    {
      if (EventGetNetworkConnectStatus() != NETWORK_CONNECT_ERROR)
      {
        if (EventGetDeviceActivationStatus() == true)
        {
          PushAlarmEventFormat_t PushAlarmEventFormat = {0};

          PushAlarmEventFormat.LogId = LogId;
          PushAlarmEventFormat.LogType = LogType;
          PushAlarmEventFormat.TiggerEn = TiggerEn;
          return EventMarkSystemNewAction(DEV_ALARM_EVENT_REPORTING, EventStartAlarmReportingTaskCallback, EventExitAlarmReportingTaskCallback, MESSAGE_SEND_TIMEOUT, false, &PushAlarmEventFormat, sizeof(PushAlarmEventFormat_t), true);
        }
      }
    }
  }
#endif

  return false;
}

bool EventGetLocalRegisterKeyStartEn(void)
{
  if (EventListFind(TaskScheduleNode, DEV_LOCAL_REGISTER) != NULL)
    return true;

  return false;
}

bool EventGetKeyInAdminPasswordTaskStartEn(void)
{
  if (EventListFind(TaskScheduleNode, DEV_KEY_IN_ADMIN_PASSWORD) != NULL)
    return true;

  return false;
}

bool EventGetVerifyNormalOpenPermissionTaskStartEn(void)
{
  if (EventListFind(TaskScheduleNode, DEV_VERIFY_NORMAL_OPEN_PERMISSION) != NULL)
    return true;

  return false;
}

bool EventExitLocalRegisterKeyTask(EventKeyType_t KeyType, const void *pKeyIn, uint8_t NumberOfKeyIn)
{
  TaskScheduleNode_t Node = EventListFind(TaskScheduleNode, DEV_LOCAL_REGISTER);
  if (Node != NULL)
  {
    if ((pKeyIn != NULL) && (NumberOfKeyIn > 0))
    {
      RegisterKeyInformation_t RegisterKeyInformation = {0};
      memcpy(&RegisterKeyInformation, Node->AttachedParam.Param, sizeof(RegisterKeyInformation_t));

      RegisterKeyInformation.NumberOfKey = NumberOfKeyIn;
      memcpy(RegisterKeyInformation.AuthenticationKey, pKeyIn, NumberOfKeyIn);
      memcpy(Node->AttachedParam.Param, &RegisterKeyInformation, sizeof(RegisterKeyInformation_t));
    }

    return EventMarkTaskExecuteComplete(DEV_LOCAL_REGISTER);
  }

  return false;
}

bool EventStartLocalRegisterKeyTask(RegisterKeyInformation_t *pRegisterInformationIn)
{
  return EventMarkSystemNewAction(DEV_LOCAL_REGISTER, EventStartLocalRegisterTaskCallback, EventExitLocalRegisterTaskCallback, EventRegisterTimeout(), false, pRegisterInformationIn, sizeof(RegisterKeyInformation_t), false);
}

bool EventExitOnlineRegisterTask(uint8_t KeyType, const void *pKeyIn, uint8_t NumberOfKeyIn)
{
  TaskScheduleNode_t Node = EventListFind(TaskScheduleNode, DEV_ONLINE_REGISTER);
  if (Node != NULL)
  {
    EventResetAccumulatedTimeOfNetworkKeepLive();

    OnlineRegisterInformation_t OnlineRegisterInformation = {0};
    memcpy(&OnlineRegisterInformation, Node->AttachedParam.Param, sizeof(OnlineRegisterInformation_t));
    if ((NumberOfKeyIn > 0) && (pKeyIn != NULL))
    {
      memcpy(OnlineRegisterInformation.KeyInformation.AuthenticationKey, pKeyIn, NumberOfKeyIn);
      memcpy(Node->AttachedParam.Param, &OnlineRegisterInformation, sizeof(OnlineRegisterInformation_t));
    }

    return EventMarkTaskExecuteComplete(DEV_ONLINE_REGISTER);
  }

  return false;
}

bool EventStartOnlineRegisterTask(OnlineRegisterInformation_t *pRegisterInformationIn)
{
  if (EventUpdateTargetActionAttachedParam(DEV_ONLINE_REGISTER, pRegisterInformationIn, sizeof(OnlineRegisterInformation_t)) == true)
  {
    EventResetTaskRuntime(DEV_ONLINE_REGISTER);
    return true;
  }

  return EventMarkSystemNewAction(DEV_ONLINE_REGISTER, EventStartOnlineRegisterTaskCallback, EventExitOnlineRegisterTaskCallback, MESSAGE_SEND_TIMEOUT, false, pRegisterInformationIn, sizeof(OnlineRegisterInformation_t), false);
}

bool EventExitExecuteUnlockTask(void)
{
  return EventMarkTaskExecuteComplete(DEV_UNLOCK);
}

bool EventExecuteUnlockTask(const uint8_t KeyType, const uint8_t *pKeyValueIn, uint32_t EndTimestamp, uint8_t UnlockType)
{
  EventCenterStatusBit.LockedStatusBit.NumberOfError = 0;

#if ((_BOARD_TYPE_ & _DA01_BOARD_) == _DA01_BOARD_)
  if (EventGetDeviceActivationStatus() != true)
  {
    UnlockType = DOOR_ACTION_NORMAL_OPEN;
  }
#endif

  if (UnlockType == DOOR_ACTION_UNLOCK)
  {
    if (EventGetNormalOpenFlagBit() == true)
    {
      UnlockType = DOOR_ACTION_NORMAL_OPEN;
    }
  }

  {
    UnlockingMethodFormat_t UnlockingMethodFormat = {0};

    UnlockingMethodFormat.KeyType = KeyType;
    UnlockingMethodFormat.UnlockingMethod = UnlockType;
    UnlockingMethodFormat.AuthorizationExpirationTime[0] = (uint8_t)((EndTimestamp & 0xFF000000) >> 24);
    UnlockingMethodFormat.AuthorizationExpirationTime[1] = (uint8_t)((EndTimestamp & 0x00FF0000) >> 16);
    UnlockingMethodFormat.AuthorizationExpirationTime[2] = (uint8_t)((EndTimestamp & 0x0000FF00) >> 8);
    UnlockingMethodFormat.AuthorizationExpirationTime[3] = (uint8_t)(EndTimestamp & 0x000000FF);
    if (pKeyValueIn != NULL)
    {
      memcpy(UnlockingMethodFormat.KeyValue, pKeyValueIn, USER_AUTHENTICATION_KEY_LENGTH);
    }

    uint8_t AutoDelete = (UnlockType == DOOR_ACTION_UNLOCK) ? false : true;
    return EventMarkSystemNewAction(DEV_UNLOCK, EventStartDoorUnlockTaskCallback, EventExitDoorUnlockTaskCallback, EventGetUnlockTime(), AutoDelete, &UnlockingMethodFormat, sizeof(UnlockingMethodFormat_t), false);
  }

  return false;
}

bool EventExitDeviceLockTipTask(void)
{
  return EventMarkTaskExecuteComplete(DEV_TIP_DEVICE_IN_LOCKED);
}

bool EventStartDeviceLockTipTask(void)
{
  return EventMarkSystemNewAction(DEV_TIP_DEVICE_IN_LOCKED, EventStartDoorLockTaskCallback, EventExitDoorLockTaskCallback, ALARM_TASK_RUN_TIMEOUT, false, NULL, 0, false);
}

bool EventExitReadCardDataTask(const void *pCardSerialNumber, uint8_t NumberOfCardSerialNumber)
{
  TaskScheduleNode_t Node = EventListFind(TaskScheduleNode, DEV_READ_CARD);
  if (Node != NULL)
  {
    if (NumberOfCardSerialNumber <= USER_AUTHENTICATION_KEY_LENGTH)
    {
      VerifyKeyFormat_t VerifyKeyFormat = {0};

      VerifyKeyFormat.KeyType = KEY_TYPE_CARD;
      VerifyKeyFormat.NumberOfKey = NumberOfCardSerialNumber;
      if ((pCardSerialNumber != NULL) && (NumberOfCardSerialNumber > 0))
      {
        memcpy(VerifyKeyFormat.KeyValue, pCardSerialNumber, NumberOfCardSerialNumber);
      }

      memcpy(Node->AttachedParam.Param, &VerifyKeyFormat, sizeof(VerifyKeyFormat_t));
      return EventMarkTaskExecuteComplete(DEV_READ_CARD);
    }
  }

  return false;
}

bool EventStartReadCardDataTask(void)
{
  // if (EventGetAntiPickingAlarmEn() != true)
  {
    // if (EventGetSystemProtectionIdentifier() != true)
    {
      return EventMarkSystemNewAction(DEV_READ_CARD, EventStartReadCardTaskCallback, EventExitReadCardTaskCallback, EventUserActionTimeout(), false, NULL, 0, false);
    }
  }

  return false;
}

bool EventExitExternalModuleVerificationTask(uint8_t KeyType, const void *pKeyIn, uint8_t NumberOfKeyIn)
{
  TaskScheduleNode_t Node = EventListFind(TaskScheduleNode, DEV_SAFETY_AUTHENTICATION);
  if (Node != NULL)
  {
    if (NumberOfKeyIn <= TYPE_THE_LENGTH_OF_KEY)
    {
      VerifyKeyFormat_t VerifyKeyFormat = {0};

      VerifyKeyFormat.KeyType = KeyType;
      VerifyKeyFormat.NumberOfKey = NumberOfKeyIn;
      if ((pKeyIn != NULL) && (NumberOfKeyIn > 0))
      {
        memcpy(VerifyKeyFormat.KeyValue, pKeyIn, NumberOfKeyIn);
      }

      memcpy(Node->AttachedParam.Param, &VerifyKeyFormat, sizeof(VerifyKeyFormat_t));
      return EventMarkTaskExecuteComplete(DEV_SAFETY_AUTHENTICATION);
    }
  }

  return false;
}

bool EventStartExternalModuleVerificationTask(void)
{
  if (EventGetAntiPickingAlarmEn() != true)
  {
    if (EventGetSystemProtectionIdentifier() != true)
    {
      return EventMarkSystemNewAction(DEV_SAFETY_AUTHENTICATION, EventStartExternalModuleVerifyTaskCallback, EventExitExternalModuleVerifyTaskCallback, EventUserActionTimeout(), false, NULL, 0, false);
    }
  }

  return false;
}

bool EventExitKeyScanfTask(const void *pKeyIn, uint8_t NumberOfKeyIn)
{
  TaskScheduleNode_t Node = EventListFind(TaskScheduleNode, DEV_KEYSCANF);
  if (Node != NULL)
  {
    if (NumberOfKeyIn <= TYPE_THE_LENGTH_OF_KEY)
    {
      VerifyKeyFormat_t VerifyKeyFormat = {0};

      VerifyKeyFormat.KeyType = KEY_TYPE_KEYBOARD;
      VerifyKeyFormat.NumberOfKey = NumberOfKeyIn;
      if ((pKeyIn != NULL) && (NumberOfKeyIn > 0))
      {
        memcpy(VerifyKeyFormat.KeyValue, pKeyIn, NumberOfKeyIn);
      }

      memcpy(Node->AttachedParam.Param, &VerifyKeyFormat, sizeof(VerifyKeyFormat_t));
      return EventMarkTaskExecuteComplete(DEV_KEYSCANF);
    }
  }

  return false;
}

bool EventStartKeyScanfTask(void)
{
  if (EventGetAntiPickingAlarmEn() != true)
  {
    if (EventGetSystemProtectionIdentifier() != true)
    {
      return EventMarkSystemNewAction(DEV_KEYSCANF, EventStartKeyboardKeyscanfTaskCallback, EventExitKeyboardKeyscanfTaskCallback, EventUserActionTimeout(), false, NULL, 0, false);
    }
  }

  return false;
}

bool EventExitLockedInTipTask(void)
{
  return EventMarkTaskExecuteComplete(DEV_TIP_LOCKED_IN);
}

bool EventStartLockedInTipTask(void)
{
  return EventMarkSystemNewAction(DEV_TIP_LOCKED_IN, EventStartLockedInTipTaskCallback, EventExitLockedInTipTaskCallback, ALARM_TASK_RUN_TIMEOUT, false, NULL, 0, false);
}

bool EventExitFalseLockedTipTask(void)
{
  return EventMarkTaskExecuteComplete(DEV_TIP_FALSE_LOCKED);
}

bool EventStartFalseLockedTipTask(void)
{
  return EventMarkSystemNewAction(DEV_TIP_FALSE_LOCKED, EventStartFalseLockedTipTaskCallback, EventExitFalseLockedTipTaskCallback, ALARM_TASK_RUN_TIMEOUT, false, NULL, 0, false);
}

bool EventExitPickLockTipTask(void)
{
  return EventMarkTaskExecuteComplete(DEV_ALARM_PICK_LOCK);
}

bool EventStartPickLockTipTask(void)
{
  return EventMarkSystemNewAction(DEV_ALARM_PICK_LOCK, EventStartPickLockedTipTaskCallback, EventExitPickLockedTipTaskCallback, ALARM_TASK_RUN_TIMEOUT, false, NULL, 0, false);
}

bool EventExitKeyInstallTipTask(void)
{
  return EventMarkTaskExecuteComplete(DEV_ALARM_KEY_IN);
}

bool EventStartKeyInstallTipTask(void)
{
  return EventMarkSystemNewAction(DEV_ALARM_KEY_IN, EventStartKeyInTipCallback, EventExitKeyInTipTaskCallback, ALARM_TASK_RUN_TIMEOUT, false, NULL, 0, false);
}

bool EventExitWirelessWakeupTask(void)
{
  return EventMarkTaskExecuteComplete(DEV_WIRELESS_WAKEUP);
}

bool EventStartWirelessWakeupTask(void)
{
  return EventMarkSystemNewAction(DEV_WIRELESS_WAKEUP, EventStartWirelessWakeupTaskCallback, EventExitWirelessWakeupTaskCallback, EventUserActionTimeout(), false, NULL, 0, false);
}

bool EventExitUpdateBluetoothRadioTask(void)
{
  return EventMarkTaskExecuteComplete(DEV_UPDATE_BLUETOOTH_RADIO);
}

bool EventStartUpdateBluetoothRadioTask(void)
{
  return EventMarkSystemNewAction(DEV_UPDATE_BLUETOOTH_RADIO, EventStartUpdateBluetoothRadioCallback, EventExitUpdateBluetoothRadioCallback, 1, true, NULL, 0, true);
}

bool EventExitStadnbyTask(void)
{
  return EventMarkTaskExecuteComplete(DEV_STANDBY);
}

bool EventStartStadnbyTask(void)
{
  return EventMarkSystemNewAction(DEV_STANDBY, EventStartStandbyTaskCallback, EventExitStandbyTaskCallback, DEVICE_STANDBY_TIMEOUT, false, NULL, 0, false);
}

bool EventGetOnlineRegisterKeyInformation(OnlineRegisterInformation_t *pRegisterInformationOut)
{
  if (pRegisterInformationOut != NULL)
  {
    TaskScheduleNode_t Node = EventListFind(TaskScheduleNode, DEV_ONLINE_REGISTER);
    if (Node != NULL)
    {
      memcpy(pRegisterInformationOut, Node->AttachedParam.Param, sizeof(OnlineRegisterInformation_t));
      return true;
    }
  }

  return false;
}

bool EventGetActionTriggerStatus(SystemAction_t Action)
{
  TaskScheduleNode_t Node = EventListFind(TaskScheduleNode, Action);
  if (Node != NULL)
    return true;

  return false;
}

bool EventResetTheRunningTimeOfSpecificAction(SystemAction_t Action)
{
  if (CurrectTaskScheduleNode != NULL)
  {
    if (CurrectTaskScheduleNode->AttachedParam.Level == Action)
    {
      EventResetAccumulatedTimeOfTaskSchedule();
      return true;
    }
  }

  return false;
}

void EventDeleteSpecificAction(SystemAction_t Action)
{
  TaskScheduleNode_t Node = EventListFind(TaskScheduleNode, Action);
  if (Node != NULL)
  {
    EventListErase(Node);
  }
}

bool EventGetSystemProtectionIdentifier(void)
{
  if (EventCenterStatusBit.LockedStatusBit.LockedEn == true)
  {
    uint32_t CurrentTime = EventGetCurrectTimestamp();

    if (EventCenterStatusBit.LockedStatusBit.EndTimestamp > CurrentTime)
    {
      EventStartDeviceLockTipTask();
      return true;
    }

    EventCenterStatusBit.LockedStatusBit.LockedEn = false;
    memset(&EventCenterStatusBit.LockedStatusBit, 0, sizeof(LockedStatusBit_t));
  }

  return false;
}

void EventMarkingModuleSelfTestResults(SelfTestOrder_t DeviceType, bool SelftestResult)
{
  switch (DeviceType)
  {
  case RFID_DEV_SELF_TEST:
    PRINT("[self-test]: rfid self-test result = %d.\r\n", SelftestResult);
    EventCenterStatusBit.SelfTestStatus.FailureIdent.FailureBit.Rfid = (SelftestResult != true) ? DEV_SELF_TEST_ERROR : DEV_SELF_TEST_SUCCESS;
    break;

  case KEYBOARD_DEV_SELF_TEST:
    PRINT("[self-test]: keyboard self-test result = %d.\r\n", SelftestResult);
    EventCenterStatusBit.SelfTestStatus.FailureIdent.FailureBit.Keyboard = (SelftestResult != true) ? DEV_SELF_TEST_ERROR : DEV_SELF_TEST_SUCCESS;
    break;

  case SAFETY_MODULE_DEV_SELF_TEST:
    PRINT("[self-test]: safety self-test result = %d.\r\n", SelftestResult);
    EventCenterStatusBit.SelfTestStatus.FailureIdent.FailureBit.Safety = (SelftestResult != true) ? DEV_SELF_TEST_ERROR : DEV_SELF_TEST_SUCCESS;
    break;

  case NETWORK_MODULE_DEV_SELF_TEST:
    PRINT("[self-test]: network self-test result = %d.\r\n", SelftestResult);
    EventCenterStatusBit.SelfTestStatus.FailureIdent.FailureBit.Network = (SelftestResult != true) ? DEV_SELF_TEST_ERROR : DEV_SELF_TEST_SUCCESS;
    break;

  default:
    break;
  }

  EventStartDeviceSelfTestTaskNoWait();
  EventCenterStatusBit.SelfTestStatus.Status = OBTAIN_SELF_TEST_EQUIPMENT;
}

void EventMarkingModuleResetResult(DeviceResetStep_t DeviceType, bool ResetResult)
{
  switch (DeviceType)
  {
  case DELETE_SAFETY_MODULE_DATA:
    PRINT("[reset]: safety device reset result = %d.\r\n", ResetResult);
    break;

  case DELETE_NETWORK_MODULE_DATA:
    PRINT("[reset]: network device reset result = %d.\r\n", ResetResult);
    break;

  default:
    break;
  }

  EventStartRestoreFactoryTaskNoWait();
  EventCenterStatusBit.DeviceResetStatus.Status = GETTING_RESET_DEVICE;
}

uint16_t EventGetRfidCommunicationFaultyIdent(void)
{
  return EventCenterStatusBit.SelfTestStatus.FailureIdent.FailureBit.Rfid;
}

uint16_t EventGetKeyboardCommunicationFaultyIdent(void)
{
  return EventCenterStatusBit.SelfTestStatus.FailureIdent.FailureBit.Keyboard;
}

uint16_t EventGetSafetyModuleCommunicationFaultyIdent(void)
{
  return EventCenterStatusBit.SelfTestStatus.FailureIdent.FailureBit.Safety;
}

uint16_t EventGetNetworkCommunicationFaultyIdent(void)
{
  return EventCenterStatusBit.SelfTestStatus.FailureIdent.FailureBit.Network;
}

SelfTestOrder_t EventGetSelfTestResult(void)
{
  return EventCenterStatusBit.SelfTestStatus.Order;
}

bool EventGetDeviceWakeupFlagBit(void)
{
  return EventCenterStatusBit.DeviceStatusBit.WakeupEn;
}

void EventSetDeviceWakeupFlagBit(bool En)
{
  EventCenterStatusBit.DeviceStatusBit.WakeupEn = En;
}

bool EventGetNormalOpenFlagBit(void)
{
  return EventCenterStatusBit.DeviceStatusBit.NormalOpenEn;
}

void EventSetNormalOpenFlagBit(bool En)
{
  EventCenterStatusBit.DeviceStatusBit.NormalOpenEn = En;
}

bool EventGetStatusUpdateFlagBit(void)
{
  return EventCenterStatusBit.DeviceStatusBit.StatusUpdateEn;
}

void EventSetStatusUpdateFlagBit(bool En)
{
  EventCenterStatusBit.DeviceStatusBit.StatusUpdateEn = En;
}

bool EventGetVoicePlayBusyFlagBit(void)
{
  return EventCenterStatusBit.DeviceStatusBit.VoicePlayBusyEn;
}

void EventSetVoicePlayBusyFlagBit(bool En)
{
  EventCenterStatusBit.DeviceStatusBit.VoicePlayBusyEn = En;
}

bool EventGetDeviceInitializationFlagBit(void)
{
  return EventCenterStatusBit.DeviceStatusBit.InitializationEn;
}

void EventSetDeviceInitializationFlagBit(bool En)
{
  EventCenterStatusBit.DeviceStatusBit.InitializationEn = En;
}

bool EventGetMessageQueueBusyFlagBit(void)
{
  return EventCenterStatusBit.DeviceStatusBit.MessageQueueBusyEn;
}

void EventSetMessageQueueBusyFlagBit(bool En)
{
  EventCenterStatusBit.DeviceStatusBit.MessageQueueBusyEn = En;
}

bool EventGetBluetoothConnectFlagBit(void)
{
  return EventCenterStatusBit.DeviceStatusBit.BluetoothConnectEn;
}

void EventSetBluetoothConnectFlagBit(bool En)
{
  EventCenterStatusBit.DeviceStatusBit.BluetoothConnectEn = En;
}

bool EventGetLogNeedToBeUploadedFlagBit(void)
{
  return EventCenterStatusBit.DeviceStatusBit.LogNeedToBeUploaded;
}

void EventSetLogNeedToBeUploadedFlagBit(bool En)
{
  EventCenterStatusBit.DeviceStatusBit.LogNeedToBeUploaded = En;
}

uint8_t EventGetNetworkConnectStatus(void)
{
  return EventCenterStatusBit.DeviceStatusBit.NetworkConnectStatus;
}

bool EventSetNetworkConnectStatus(uint8_t Status)
{
  switch (Status)
  {
  case NETWORK_CLOSED:
  case NETWORK_CONNECT_ERROR:
  case NETWORK_CONNECT_SUCCESS:
  case NETWORK_LINKS_BEING_ESTABLISHED:
    EventCenterStatusBit.DeviceStatusBit.NetworkConnectStatus = Status;
    return true;
  }

  return false;
}

void EventSystemStartup(void)
{
  PRINT("[system]: startup.\r\n");
  PRINT("[system]: ===software verion = %s\r\n", DEFAULT_FIRMWARE_VERSION);

  EventInitialisingDeviceParameters();
  EventRealTimeInitialization();

  EventBatteryStartGetPercentageOfElectricity();
  EventUpdateBluetoothRadio();
  EventStartDeviceSelfTestTask();
  EventMotorPowerUpInitialization();

  EventCreateTaskScheduleTimer();
  EventCreateNetworkKeepLiveTimer();
  EventCreateGetServerMessageTimer();
  EventCreateAuthenticationErrorResetTimer();
  EventStartScheduleTaskNoWait();
}

void EventDeviceAutiLock(uint8_t KeyType)
{
  if (EventJudgeIfAuthFailureLimitReached(KeyType) != true)
  {
    EventPlayDeciceAutiLock();
  }
}

void EventCardReplace(uint8_t KeyType)
{
  if (EventJudgeIfAuthFailureLimitReached(KeyType) != true)
  {
    EventPlayCardReplace();
  }
}

void EventCardAffiliationError(void)
{
  if (EventJudgeIfAuthFailureLimitReached(KEY_TYPE_CARD) != true)
  {
    EventPlayCardAffiliationError();
  }
}

void EventThisFunctionCardHasBeenDisabled(void)
{
  if (EventJudgeIfAuthFailureLimitReached(KEY_TYPE_CARD) != true)
  {
    EventPlayThisFunctionCardHasBeenDisabled();
  }
}

void EventHintParameterSetStatus(uint8_t SetResult)
{
  (SetResult == true) ? EventPlaySetParameterSuccess() : EventPlaySetParameterError();
}

void EventCardholderOutOfDate(uint8_t KeyType)
{
  if (EventJudgeIfAuthFailureLimitReached(KeyType) != true)
  {
    EventPlayAudioOfOutOfDate();
  }
}

void EventCardholderAuthenticationError(uint8_t KeyType)
{
  if (EventJudgeIfAuthFailureLimitReached(KeyType) != true)
  {
    EventPlayAudioOfAuthenticationFailure();
  }
}

void EventNetworkDisconnect(void)
{
  EventResetNetworkStatus();
  EventSetNetworkConnectStatus(NETWORK_CLOSED);
}

bool EventAddNewTimedTask(TimedListNode_t NewItem, uint32_t Time, TimedTaskLevel Level, ScheduledTask_t TaskCallback, bool Start)
{
  if (NewItem != NULL)
  {
    NewItem->NextItem = NULL;
    NewItem->PreviousItem = TimedListNode;

    NewItem->En = Start;
    NewItem->Level = Level;
    NewItem->AccruedTime = 0;
    NewItem->TriggerTime = Time;
    NewItem->ScheduledTask = TaskCallback;

    TimedListNode = NewItem;
    return true;
  }

  return false;
}

bool EventAddNewEventHandler(EventHandlerListNode_t NewItem, EventHandler_t EventHandler)
{
  if (NewItem != NULL)
  {
    NewItem->NextItem = NULL;
    NewItem->PreviousItem = EventHandlerListNode;
    NewItem->Handler = EventHandler;

    EventHandlerListNode = NewItem;
    return true;
  }

  return false;
}

void EventDataHandler(void)
{
  EventHandlerListNode_t TmpListNode = EventHandlerListNode;

  while (TmpListNode != NULL)
  {
    if (TmpListNode->Handler != NULL)
    {
      TmpListNode->Handler();
    }

    TmpListNode = TmpListNode->PreviousItem;
  }
}

void EventCenterConfiguration(void)
{
  EventCenterExternalInterfaces_t ExternalInterfaces = {0};

  ExternalInterfaces.TaskSchedule = EventTaskScheduledCallback;
  ExternalInterfaces.ScheduledTask = EventScheduledTaskCallback;
  ExternalInterfaces.DeviceRebootTask = EventDeviceRebootCallback;
  ExternalInterfaces.RestoreFactoryTask = EventRestoreFactoryCallback;
  ExternalInterfaces.DeviceSelfTestTask = EventDeviceSelfTestCallback;
  ExternalInterfaces.FirmwareUpdateTask = SystemFirmwarwUpdateCallback;
  EventCenterBoardInitialisation(&ExternalInterfaces);

  EventInitialisingTaskSchedule();
  memset(&EventCenterStatusBit, 0, sizeof(EventCenterStatusBit_t));
}
